bug-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: a few Q's


From: Christos Zoulas
Subject: Re: a few Q's
Date: Fri, 24 Oct 2003 22:28:58 -0400

On Oct 24,  5:18pm, derek@ximbiot.com (Derek Robert Price) wrote:
-- Subject: Re: a few Q's

And here I go, as promised [patch 1]:

1. use xasprintf() in most places where it is easily done, and simplify
   the code in the process. This actually eliminates *a lot* of duplicate
   string scanning. Don't use the ugly slop code that makes assumptions
   about the lengths of strings.
2. simplify and factor out common repository path manipulation code.
3. use const everywhere possible, to make sure that strings don't get
   unintentionally modified.

There is a variety of indentation styles in the code. What is the
sanction style for continuation lines?

If you need any more explanations, please let me know. If/when this is
accepted, I will proceed the second part (setuid changes).

Yes, this is a big diff, but the existing string manipulation in the
code was ugly and unmaintainable. Using xasprintf() in a lot of places,
make the test easier to read and make changes to.

Enjoy,

christos
   
Index: diff/diff.c
===================================================================
RCS file: /cvs/ccvs/diff/diff.c,v
retrieving revision 1.13
diff -u -u -r1.13 diff.c
--- diff/diff.c 29 Apr 2002 01:41:15 -0000      1.13
+++ diff/diff.c 25 Oct 2003 02:17:27 -0000
@@ -237,7 +237,7 @@
 diff_run (argc, argv, out, callbacks_arg)
      int argc;
      char *argv[];
-     char *out;
+     const char *out;
      const struct diff_callbacks *callbacks_arg;
 {
   int val;
Index: diff/diff3.c
===================================================================
RCS file: /cvs/ccvs/diff/diff3.c,v
retrieving revision 1.15
diff -u -u -r1.15 diff3.c
--- diff/diff3.c        13 Jun 2003 15:08:10 -0000      1.15
+++ diff/diff3.c        25 Oct 2003 02:17:27 -0000
@@ -253,7 +253,7 @@
 diff3_run (argc, argv, out, callbacks_arg)
      int argc;
      char **argv;
-     char *out;
+     const char *out;
      const struct diff_callbacks *callbacks_arg;
 {
   int c, i;
Index: diff/diffrun.h
===================================================================
RCS file: /cvs/ccvs/diff/diffrun.h,v
retrieving revision 1.4
diff -u -u -r1.4 diffrun.h
--- diff/diffrun.h      12 Jan 1999 20:36:09 -0000      1.4
+++ diff/diffrun.h      25 Oct 2003 02:17:27 -0000
@@ -56,12 +56,12 @@
 
 /* Run a diff.  */
 
-extern int diff_run DIFFPARAMS((int, char **, char *,
+extern int diff_run DIFFPARAMS((int, char **, const char *,
                                const struct diff_callbacks *));
 
 /* Run a diff3.  */
 
-extern int diff3_run DIFFPARAMS((int, char **, char *,
+extern int diff3_run DIFFPARAMS((int, char **, const char *,
                                 const struct diff_callbacks *));
 
 #undef DIFFPARAMS
Index: src/add.c
===================================================================
RCS file: /cvs/ccvs/src/add.c,v
retrieving revision 1.95
diff -u -u -r1.95 add.c
--- src/add.c   5 Oct 2003 00:37:16 -0000       1.95
+++ src/add.c   25 Oct 2003 02:17:28 -0000
@@ -29,8 +29,9 @@
 #include "fileattr.h"
 
 static int add_directory (struct file_info *finfo);
-static int build_entry (char *repository, char *user, char *options,
-                       char *message, List * entries, char *tag);
+static int build_entry (const char *repository, const char *user,
+                       const char *options, const char *message,
+                       List * entries, const char *tag);
 
 static const char *const add_usage[] =
 {
@@ -45,6 +46,7 @@
 add (int argc, char **argv)
 {
     char *message = NULL;
+    char *free_fullname = NULL;
     int i;
     char *repository;
     int c;
@@ -241,8 +243,7 @@
                   per-directory tags */
                ParseTag (&tag, &date, &nonbranch);
 
-               rcsdir = xmalloc (strlen (repository) + strlen (p) + 5);
-               sprintf (rcsdir, "%s/%s", repository, p);
+               (void) xasprintf (&rcsdir, "%s/%s", repository, p);
 
                Create_Admin (p, argv[j], rcsdir, tag, date,
                              nonbranch, 0, 1);
@@ -297,7 +298,7 @@
        if (save_cwd (&cwd))
            exit (EXIT_FAILURE);
 
-       finfo.fullname = xstrdup (argv[i]);
+       finfo.fullname = free_fullname = xstrdup (argv[i]);
        p = last_component (argv[i]);
        if (p == argv[i])
        {
@@ -415,10 +416,8 @@
                     * See if a directory exists in the repository with
                     * the same name.  If so, blow this request off.
                     */
-                   char *dname = xmalloc (strlen (repository)
-                                          + strlen (finfo.file)
-                                          + 10);
-                   (void) sprintf (dname, "%s/%s", repository, finfo.file);
+                   char *dname;
+                   (void) xasprintf (&dname, "%s/%s", repository, finfo.file);
                    if (isdir (dname))
                    {
                        error (0, 0,
@@ -576,8 +575,7 @@
                    (void) strcpy (tmp, vers->vn_user + 1);
                    (void) strcpy (vers->vn_user, tmp);
                    free( tmp );
-                   tmp = xmalloc( strlen( finfo.file ) + 13 );
-                   (void) sprintf (tmp, "Resurrected %s", finfo.file);
+                   (void) xasprintf (&tmp, "Resurrected %s", finfo.file);
                    Register (entries, finfo.file, vers->vn_user, tmp,
                              vers->options,
                              vers->tag, vers->date, vers->ts_conflict);
@@ -640,7 +638,11 @@
            exit (EXIT_FAILURE);
        free_cwd (&cwd);
 
-       free (finfo.fullname);
+       if (free_fullname)
+       {
+           free (free_fullname);
+           finfo.fullname = NULL;
+       }
 #if defined (SERVER_SUPPORT) && !defined (FILENAMES_CASE_INSENSITIVE)
        if (found_name != NULL)
            free (found_name);
@@ -669,13 +671,15 @@
 static int
 add_directory (struct file_info *finfo)
 {
-    char *repository = finfo->repository;
+    const char *repository = finfo->repository;
     List *entries = finfo->entries;
-    char *dir = finfo->file;
+    const char *dir = finfo->file;
 
     char *rcsdir = NULL;
     struct saved_cwd cwd;
     char *message = NULL;
+    char *message_tag = "";
+    char *message_date = "";
     char *tag, *date;
     int nonbranch;
     char *attrs;
@@ -720,8 +724,7 @@
        goto out;
     }
 
-    rcsdir = xmalloc (strlen (repository) + strlen (dir) + 5);
-    sprintf (rcsdir, "%s/%s", repository, dir);
+    (void) xasprintf (&rcsdir, "%s/%s", repository, dir);
     if (isfile (rcsdir) && !isdir (rcsdir))
     {
        error (0, 0, "%s is not a directory; %s not added", rcsdir,
@@ -729,25 +732,24 @@
        goto out;
     }
 
-    /* setup the log message */
-    message = xmalloc (strlen (rcsdir)
-                      + 36
-                      + (tag == NULL ? 0 : strlen (tag) + 38)
-                      + (date == NULL ? 0 : strlen (date) + 39));
-    (void) sprintf (message, "Directory %s added to the repository\n",
-                   rcsdir);
     if (tag)
     {
-       (void) strcat (message, "--> Using per-directory sticky tag `");
-       (void) strcat (message, tag);
-       (void) strcat (message, "'\n");
+       (void) xasprintf(&message_tag, "--> Using per-directory sticky tag 
`%s'\n",
+           tag);
     }
     if (date)
     {
-       (void) strcat (message, "--> Using per-directory sticky date `");
-       (void) strcat (message, date);
-       (void) strcat (message, "'\n");
+       (void) xasprintf(&message_date, "--> Using per-directory sticky date 
`%s'\n",
+           date);
     }
+    /* setup the log message */
+    (void) xasprintf (&message, "Directory %s added to the repository\n%s%s",
+                   rcsdir, message_tag, message_date);
+
+    if (tag)
+       free(message_tag);
+    if (date)
+       free(message_date);
 
     if (!isdir (rcsdir))
     {
@@ -843,7 +845,8 @@
  * interrogating the user.  Returns non-zero on error.
  */
 static int
-build_entry (char *repository, char *user, char *options, char *message, List 
*entries, char *tag)
+build_entry (const char *repository, const char *user, const char *options,
+    const char *message, List *entries, const char *tag)
 {
     char *fname;
     char *line;
@@ -857,8 +860,7 @@
      * file user,t.  If the "message" argument is set, use it as the
      * initial creation log (which typically describes the file).
      */
-    fname = xmalloc (strlen (user) + 80);
-    (void) sprintf (fname, "%s/%s%s", CVSADM, user, CVSEXT_LOG);
+    (void) xasprintf (&fname, "%s/%s%s", CVSADM, user, CVSEXT_LOG);
     fp = open_file (fname, "w+");
     if (message && fputs (message, fp) == EOF)
            error (1, errno, "cannot write to %s", fname);
@@ -871,8 +873,7 @@
      * without needing to clean anything up (well, we could clean up the
      * ,t file, but who cares).
      */
-    line = xmalloc (strlen (user) + 20);
-    (void) sprintf (line, "Initial %s", user);
+    (void) xasprintf (&line, "Initial %s", user);
     Register (entries, user, "0", line, options, tag, (char *) 0, (char *) 0);
     free (line);
     return (0);
Index: src/admin.c
===================================================================
RCS file: /cvs/ccvs/src/admin.c,v
retrieving revision 1.92
diff -u -u -r1.92 admin.c
--- src/admin.c 18 Oct 2003 21:01:26 -0000      1.92
+++ src/admin.c 25 Oct 2003 02:17:28 -0000
@@ -14,8 +14,8 @@
 #include <grp.h>
 #endif
 
-static Dtype admin_dirproc (void *callerdat, char *dir,
-                                  char *repos, char *update_dir,
+static Dtype admin_dirproc (void *callerdat, const char *dir,
+                                  const char *repos, const char *update_dir,
                                   List *entries);
 static int admin_fileproc (void *callerdat, struct file_info *finfo);
 
@@ -187,11 +187,7 @@
                if (optarg == NULL)
                    admin_data.branch = xstrdup ("-b");
                else
-               {
-                   admin_data.branch = xmalloc (strlen (optarg) + 5);
-                   strcpy (admin_data.branch, "-b");
-                   strcat (admin_data.branch, optarg);
-               }
+                   (void) xasprintf (&admin_data.branch, "-b%s", optarg);
                break;
 
            case 'c':
@@ -200,9 +196,7 @@
                    error (0, 0, "duplicate 'c' option");
                    goto usage_error;
                }
-               admin_data.comment = xmalloc (strlen (optarg) + 5);
-               strcpy (admin_data.comment, "-c");
-               strcat (admin_data.comment, optarg);
+               (void) xasprintf (&admin_data.comment, "-c%s", optarg);
                break;
 
            case 'a':
@@ -294,9 +288,7 @@
                    error (0, 0, "duplicate '-o' option");
                    goto usage_error;
                }
-               admin_data.delete_revs = xmalloc (strlen (optarg) + 5);
-               strcpy (admin_data.delete_revs, "-o");
-               strcat (admin_data.delete_revs, optarg);
+               (void) xasprintf (&admin_data.delete_revs, "-o%s", optarg);
                break;
 
            case 's':
@@ -923,7 +915,8 @@
  */
 /* ARGSUSED */
 static Dtype
-admin_dirproc (void *callerdat, char *dir, char *repos, char *update_dir, List 
*entries)
+admin_dirproc (void *callerdat, const char *dir, const char *repos,
+    const char *update_dir, List *entries)
 {
     if (!quiet)
        error (0, 0, "Administrating %s", update_dir);
Index: src/annotate.c
===================================================================
RCS file: /cvs/ccvs/src/annotate.c,v
retrieving revision 1.12
diff -u -u -r1.12 annotate.c
--- src/annotate.c      23 Jul 2003 20:42:25 -0000      1.12
+++ src/annotate.c      25 Oct 2003 02:17:28 -0000
@@ -25,9 +25,9 @@
 static int is_rannotate;
 
 static int annotate_fileproc (void *callerdat, struct file_info *);
-static int rannotate_proc (int argc, char **argv, char *xwhere,
-                                char *mwhere, char *mfile, int shorten,
-                                int local, char *mname, char *msg);
+static int rannotate_proc (int argc, char **argv, const char *xwhere,
+                          const char *mwhere, const char *mfile, int shorten,
+                          int local, const char *mname, const char *msg);
 
 static const char *const annotate_usage[] =
 {
@@ -134,15 +134,16 @@
        for (i = 0; i < argc; i++)
        {
            err += do_module (db, argv[i], MISC, "Annotating", rannotate_proc,
-                            (char *) NULL, 0, local, 0, 0, (char *) NULL);
+                            (const char *) NULL, 0, local, 0, 0,
+                            (const char *) NULL);
        }
        close_module (db);
     }
     else
     {
-       err = rannotate_proc (argc + 1, argv - 1, (char *) NULL,
-                        (char *) NULL, (char *) NULL, 0, local, (char *) NULL,
-                        (char *) NULL);
+       err = rannotate_proc (argc + 1, argv - 1, (const char *) NULL,
+                        (const char *) NULL, (const char *) NULL, 0, local,
+                        (const char *) NULL, (const char *) NULL);
     }
 
     return err;
@@ -150,10 +151,10 @@
     
 
 static int
-rannotate_proc (int argc, char **argv, char *xwhere, char *mwhere, char 
*mfile, int shorten, int local, char *mname, char *msg)
+rannotate_proc (int argc, char **argv, const char *xwhere,
+    const char *mwhere, const char *mfile, int shorten, int local,
+    const char *mname, const char *msg)
 {
-    /* Begin section which is identical to patch_proc--should this
-       be abstracted out somehow?  */
     char *myargv[2];
     int err = 0;
     int which;
@@ -162,58 +163,9 @@
 
     if (is_rannotate)
     {
-       repository = xmalloc (strlen (current_parsed_root->directory) + strlen 
(argv[0])
-                             + (mfile == NULL ? 0 : strlen (mfile) + 1) + 2);
-       (void) sprintf (repository, "%s/%s", current_parsed_root->directory, 
argv[0]);
-       where = xmalloc (strlen (argv[0]) + (mfile == NULL ? 0 : strlen (mfile) 
+ 1)
-                        + 1);
-       (void) strcpy (where, argv[0]);
-
-       /* if mfile isn't null, we need to set up to do only part of the module 
*/
-       if (mfile != NULL)
-       {
-           char *cp;
-           char *path;
-
-           /* if the portion of the module is a path, put the dir part on 
repos */
-           if ((cp = strrchr (mfile, '/')) != NULL)
-           {
-               *cp = '\0';
-               (void) strcat (repository, "/");
-               (void) strcat (repository, mfile);
-               (void) strcat (where, "/");
-               (void) strcat (where, mfile);
-               mfile = cp + 1;
-           }
-
-           /* take care of the rest */
-           path = xmalloc (strlen (repository) + strlen (mfile) + 5);
-           (void) sprintf (path, "%s/%s", repository, mfile);
-           if (isdir (path))
-           {
-               /* directory means repository gets the dir tacked on */
-               (void) strcpy (repository, path);
-               (void) strcat (where, "/");
-               (void) strcat (where, mfile);
-           }
-           else
-           {
-               myargv[0] = argv[0];
-               myargv[1] = mfile;
-               argc = 2;
-               argv = myargv;
-           }
-           free (path);
-       }
-
-       /* cd to the starting repository */
-       if ( CVS_CHDIR (repository) < 0)
-       {
-           error (0, errno, "cannot chdir to %s", repository);
-           free (repository);
-           return (1);
-       }
-       /* End section which is identical to patch_proc.  */
+       if (get_repository(&repository, &where, mfile, &argc, &argv, myargv)
+           == 0)
+           return -1;
 
        if (force_tag_match && tag != NULL)
            which = W_REPOS | W_ATTIC;
Index: src/checkin.c
===================================================================
RCS file: /cvs/ccvs/src/checkin.c,v
retrieving revision 1.48
diff -u -u -r1.48 checkin.c
--- src/checkin.c       19 Aug 2003 13:35:15 -0000      1.48
+++ src/checkin.c       25 Oct 2003 02:17:28 -0000
@@ -20,8 +20,8 @@
 #include "edit.h"
 
 int
-Checkin (int type, struct file_info *finfo, char *rev, char *tag,
-        char *options, char *message)
+Checkin (int type, struct file_info *finfo, const char *rev, const char *tag,
+        const char *options, const char *message)
 {
     Vers_TS *vers;
     int set_time;
@@ -72,7 +72,7 @@
               we are not expanding RCS keywords, we are done.  */
 
            if (strcmp (options, "-V4") == 0) /* upgrade to V5 now */
-               options[0] = '\0';
+               options = "";
 
            /* FIXME: If PreservePermissions is on, RCS_cmp_file is
                going to call RCS_checkout into a temporary file
@@ -84,7 +84,7 @@
                  && options != NULL
                  && ( strcmp( options, "-ko" ) == 0
                       || strcmp( options, "-kb" ) == 0 ) )
-               || RCS_cmp_file( finfo->rcs, rev, (char **)NULL, (char *)NULL,
+               || RCS_cmp_file( finfo->rcs, rev, (char **)NULL, NULL,
                                 options, finfo->file ) == 0 )
            {
                /* The existing file is correct.  We don't have to do
@@ -95,7 +95,8 @@
            {
                /* The existing file is incorrect.  We need to check
                    out the correct file contents.  */
-               if (RCS_checkout (finfo->rcs, finfo->file, rev, (char *) NULL,
+               if (RCS_checkout (finfo->rcs, finfo->file, rev,
+                                 (const char *)NULL,
                                  options, RUN_TTY, (RCSCHECKOUTPROC) NULL,
                                  (void *) NULL) != 0)
                    error (1, 0, "failed when checking out new copy of %s",
Index: src/checkout.c
===================================================================
RCS file: /cvs/ccvs/src/checkout.c,v
retrieving revision 1.119
diff -u -u -r1.119 checkout.c
--- src/checkout.c      19 Aug 2003 13:35:15 -0000      1.119
+++ src/checkout.c      25 Oct 2003 02:17:28 -0000
@@ -36,10 +36,10 @@
 #include "cvs.h"
 
 static char *findslash (char *start, char *p);
-static int checkout_proc (int argc, char **argv, char *where,
-                         char *mwhere, char *mfile, int shorten,
-                         int local_specified, char *omodule,
-                         char *msg);
+static int checkout_proc (int argc, char **argv, const char *where,
+                         const char *mwhere, const char *mfile, int shorten,
+                         int local_specified, const char *omodule,
+                         const char *msg);
 
 static const char *const checkout_usage[] =
 {
@@ -364,8 +364,7 @@
            history_name = date;
        else
        {
-           history_name = xmalloc (strlen (tag) + strlen (date) + 2);
-           sprintf (history_name, "%s:%s", tag, date);
+           (void) xasprintf (&history_name, "%s:%s", tag, date);
        }
     }
 
@@ -373,7 +372,7 @@
     for (i = 0; i < argc; i++)
        err += do_module (db, argv[i], m_type, "Updating", checkout_proc,
                          where, shorten, local, run_module_prog, !pipeout,
-                         (char *) NULL);
+                         (const char *) NULL);
     close_module (db);
     if (options)
     {
@@ -411,7 +410,7 @@
  *  being able to resolve a path or failing ot chdir to a path.
  */
 int
-safe_location (char *where)
+safe_location (const char *where)
 {
     char *current;
     char *where_location;
@@ -579,7 +578,9 @@
  */
 /* ARGSUSED */
 static int
-checkout_proc (int argc, char **argv, char *where_orig, char *mwhere, char 
*mfile, int shorten, int local_specified, char *omodule, char *msg)
+checkout_proc (int argc, char **argv, const char *where_orig,
+    const char *mwhere, const char *mfile, int shorten, int local_specified,
+    const char *omodule, const char *msg)
 {
     char *myargv[2];
     int err = 0;
@@ -619,19 +620,12 @@
        space than necessary here so that we don't have to keep
        reallocaing it later on. */
     
-    where = xmalloc (strlen (argv[0])
-                    + (mfile == NULL ? 0 : strlen (mfile))
-                    + (mwhere == NULL ? 0 : strlen (mwhere))
-                    + (where_orig == NULL ? 0 : strlen (where_orig))
-                    + 10);
-
     /* Yes, this could be written in a less verbose way, but in this
        form it is quite easy to read.
     
        FIXME?  The following code that sets should probably be moved
        to do_module in modules.c, since there is similar code in
        patch.c and rtag.c. */
-    
     if (shorten)
     {
        if (where_orig != NULL)
@@ -639,45 +633,41 @@
            /* If the user has specified a directory with `-d' on the
               command line, use it preferentially, even over the `-d'
               flag in the modules file. */
-    
-           (void) strcpy (where, where_orig);
+           where = xstrdup (where_orig);
        }
        else if (mwhere != NULL)
        {
            /* Second preference is the value of mwhere, which is from
               the `-d' flag in the modules file. */
 
-           (void) strcpy (where, mwhere);
+           where = xstrdup (where_orig);
        }
        else
        {
            /* Third preference is the directory specified in argv[0]
               which is this module'e directory in the repository. */
            
-           (void) strcpy (where, argv[0]);
+           where = xstrdup (argv[0]);
        }
     }
     else
     {
-       /* Use the same preferences here, bug don't shorten -- that
-           is, tack on where_orig if it exists. */
-
-       *where = '\0';
-
-       if (where_orig != NULL)
-       {
-           (void) strcat (where, where_orig);
-           (void) strcat (where, "/");
-       }
-
        /* If the -d flag in the modules file specified an absolute
            directory, let the user override it with the command-line
            -d option. */
 
        if ((mwhere != NULL) && (! isabsolute (mwhere)))
-           (void) strcat (where, mwhere);
+           (void) xasprintf (&where, "%s/%s", where_orig, mwhere);
+       else
+           mwhere = argv[0];
+
+       /* Use the same preferences here, bug don't shorten -- that
+           is, tack on where_orig if it exists. */
+
+       if (where_orig)
+           (void) xasprintf (&where, "%s/%s", where_orig, mwhere);
        else
-           (void) strcat (where, argv[0]);
+           where = xstrdup (mwhere);
     }
     strip_trailing_slashes (where); /* necessary? */
 
@@ -687,69 +677,7 @@
        where, repository, and argv as appropriate. */
 
     if (mfile != NULL)
-    {
-       /* The mfile variable can have one or more path elements.  If
-          it has multiple elements, we want to tack those onto both
-          repository and where.  The last element may refer to either
-          a file or directory.  Here's what to do:
-
-          it refers to a directory
-            -> simply tack it on to where and repository
-          it refers to a file
-            -> munge argv to contain `basename mfile` */
-
-       char *cp;
-       char *path;
-
-
-       /* Paranoia check. */
-
-       if (mfile[strlen (mfile) - 1] == '/')
-       {
-           error (0, 0, "checkout_proc: trailing slash on mfile (%s)!",
-                  mfile);
-       }
-
-
-       /* Does mfile have multiple path elements? */
-
-       cp = strrchr (mfile, '/');
-       if (cp != NULL)
-       {
-           *cp = '\0';
-           (void) strcat (repository, "/");
-           (void) strcat (repository, mfile);
-           (void) strcat (where, "/");
-           (void) strcat (where, mfile);
-           mfile = cp + 1;
-       }
-       
-
-       /* Now mfile is a single path element. */
-
-       path = xmalloc (strlen (repository) + strlen (mfile) + 5);
-       (void) sprintf (path, "%s/%s", repository, mfile);
-       if (isdir (path))
-       {
-           /* It's a directory, so tack it on to repository and
-               where, as we did above. */
-
-           (void) strcat (repository, "/");
-           (void) strcat (repository, mfile);
-           (void) strcat (where, "/");
-           (void) strcat (where, mfile);
-       }
-       else
-       {
-           /* It's a file, which means we have to screw around with
-               argv. */
-           myargv[0] = argv[0];
-           myargv[1] = mfile;
-           argc = 2;
-           argv = myargv;
-       }
-       free (path);
-    }
+       handle_mfile (repository, where, mfile, &argc, &argv, myargv);
 
     if (preload_update_dir != NULL)
     {
@@ -1111,8 +1039,7 @@
                               force_tag_match, 0);
            if (vers->ts_user == NULL)
            {
-               line = xmalloc (strlen (finfo.file) + 15);
-               (void) sprintf (line, "Initial %s", finfo.file);
+               (void) xasprintf (&line, "Initial %s", finfo.file);
                Register (entries, finfo.file,
                          vers->vn_rcs ? vers->vn_rcs : "0",
                          line, vers->options, vers->tag,
@@ -1166,11 +1093,7 @@
 {
     char *repository;
 
-    repository = xmalloc (strlen (current_parsed_root->directory) 
-                         + sizeof (CVSROOTADM)
-                         + sizeof (CVSNULLREPOS)
-                         + 3);
-    (void) sprintf (repository, "%s/%s/%s", current_parsed_root->directory,
+    (void) xasprintf (&repository, "%s/%s/%s", current_parsed_root->directory,
                    CVSROOTADM, CVSNULLREPOS);
     if (!isfile (repository))
     {
Index: src/classify.c
===================================================================
RCS file: /cvs/ccvs/src/classify.c,v
retrieving revision 1.29
diff -u -u -r1.29 classify.c
--- src/classify.c      23 Jul 2003 20:42:25 -0000      1.29
+++ src/classify.c      25 Oct 2003 02:17:29 -0000
@@ -16,7 +16,9 @@
  * Classify the state of a file
  */
 Ctype
-Classify_File (struct file_info *finfo, char *tag, char *date, char *options, 
int force_tag_match, int aflag, Vers_TS **versp, int pipeout)
+Classify_File (struct file_info *finfo, const char *tag, const char *date,
+    const char *options, int force_tag_match, int aflag, Vers_TS **versp,
+    int pipeout)
                             
               
                
Index: src/client.c
===================================================================
RCS file: /cvs/ccvs/src/client.c,v
retrieving revision 1.350
diff -u -u -r1.350 client.c
--- src/client.c        5 Oct 2003 00:37:16 -0000       1.350
+++ src/client.c        25 Oct 2003 02:17:30 -0000
@@ -35,7 +35,7 @@
 #   include "kerberos4-client.h"
 # endif
 
-static void add_prune_candidate (char *);
+static void add_prune_candidate (const char *);
 
 /* All the commands.  */
 int add (int argc, char **argv);
@@ -228,7 +228,7 @@
 char *
 mode_to_string (mode_t mode)
 {
-    char buf[18], u[4], g[4], o[4];
+    char *buf, u[4], g[4], o[4];
     int i;
 
     i = 0;
@@ -249,8 +249,8 @@
     if (mode & S_IXOTH) o[i++] = 'x';
     o[i] = '\0';
 
-    sprintf(buf, "u=%s,g=%s,o=%s", u, g, o);
-    return xstrdup(buf);
+    (void) xasprintf (&buf, "u=%s,g=%s,o=%s", u, g, o);
+    return buf;
 }
 
 /*
@@ -1390,16 +1390,15 @@
            return;
        }
 
-       temp_filename = xmalloc (strlen (filename) + 80);
 #ifdef USE_VMS_FILENAMES
         /* A VMS rename of "blah.dat" to "foo" to implies a
            destination of "foo.dat" which is unfortinate for CVS */
-       sprintf (temp_filename, "%s_new_", filename);
+       (void) xasprintf (&temp_filename, "%s_new_", filename);
 #else
 #ifdef _POSIX_NO_TRUNC
-       sprintf (temp_filename, ".new.%.9s", filename);
+       (void) xasprintf (&temp_filename, ".new.%.9s", filename);
 #else /* _POSIX_NO_TRUNC */
-       sprintf (temp_filename, ".new.%s", filename);
+       (void) xasprintf (&temp_filename, ".new.%s", filename);
 #endif /* _POSIX_NO_TRUNC */
 #endif /* USE_VMS_FILENAMES */
 
@@ -2011,10 +2010,8 @@
 static void
 template( char *data, List *ent_list, char *short_pathname, char *filename )
 {
-    char *buf = xmalloc ( strlen ( short_pathname )
-                         + strlen ( CVSADM_TEMPLATE )
-                         + 2 );
-    sprintf ( buf, "%s/%s", short_pathname, CVSADM_TEMPLATE );
+    char *buf;
+    (void) xasprintf ( &buf, "%s/%s", short_pathname, CVSADM_TEMPLATE );
     read_counted_file ( CVSADM_TEMPLATE, buf );
     free ( buf );
 }
@@ -2051,7 +2048,7 @@
 struct save_dir *prune_candidates;
 
 static void
-add_prune_candidate( char *dir )
+add_prune_candidate(const char *dir )
 {
     struct save_dir *p;
 
@@ -2108,10 +2105,10 @@
 static char *last_repos;
 static char *last_update_dir;
 
-static void send_repository (char *, char *, char *);
+static void send_repository (const char *, const char *, const char *);
 
 static void
-send_repository( char *dir, char *repos, char *update_dir )
+send_repository( const char *dir, const char *repos, const char *update_dir )
 {
     char *adm_name;
 
@@ -2174,7 +2171,7 @@
           sort of duplicates code elsewhere, but each
           case seems slightly different...  */
        char buf[1];
-       char *p = update_dir;
+       const char *p = update_dir;
        while (*p != '\0')
        {
            assert (*p != '\012');
@@ -2253,7 +2250,8 @@
 /* Send a Repository line and set toplevel_repos.  */
 
 void
-send_a_repository( char *dir, char *repository, char *update_dir )
+send_a_repository( const char *dir, const char *repository,
+    const char *update_dir )
 {
     if (toplevel_repos == NULL && repository != NULL)
     {
@@ -2274,6 +2272,7 @@
                toplevel_repos = Name_Repository (update_dir, update_dir);
            else
            {
+               char *upd_dir;
                /*
                 * Guess the repository of that directory by looking at a
                 * subdirectory and removing as many pathname components
@@ -2303,10 +2302,11 @@
 
                int repository_len, update_dir_len;
 
-               strip_trailing_slashes (update_dir);
+               upd_dir = xstrdup (update_dir);
+               strip_trailing_slashes (upd_dir);
 
                repository_len = strlen (repository);
-               update_dir_len = strlen (update_dir);
+               update_dir_len = strlen (upd_dir);
 
                /* Try to remove the path components in UPDATE_DIR
                    from REPOSITORY.  If the path elements don't exist
@@ -2316,7 +2316,7 @@
                    current_parsed_root->directory. */
                if ((repository_len > update_dir_len)
                    && (strcmp (repository + repository_len - update_dir_len,
-                               update_dir) == 0)
+                               upd_dir) == 0)
                    /* TOPLEVEL_REPOS shouldn't be above 
current_parsed_root->directory */
                    && ((size_t)(repository_len - update_dir_len)
                        > strlen (current_parsed_root->directory)))
@@ -2335,6 +2335,7 @@
                {
                    toplevel_repos = xstrdup (current_parsed_root->directory);
                }
+               free (upd_dir);
            }
        }
     }
@@ -2732,7 +2733,7 @@
  * contain 0's.
  */
 void
-send_to_server_via( struct buffer *via_buffer, char *str, size_t len )
+send_to_server_via( struct buffer *via_buffer, const char *str, size_t len )
 {
     static int nbytes;
 
@@ -2757,7 +2758,7 @@
 }
 
 void
-send_to_server( char *str, size_t len )
+send_to_server( const char *str, size_t len )
 {
   send_to_server_via (global_to_server, str, len);
 }
@@ -3736,10 +3737,10 @@
 
 /* Send an argument STRING.  */
 void
-send_arg( char *string )
+send_arg( const char *string )
 {
     char buf[1];
-    char *p = string;
+    const char *p = string;
 
     send_to_server ("Argument ", 0);
 
@@ -3759,14 +3760,14 @@
     send_to_server ("\012", 1);
 }
 
-static void send_modified (char *, char *, Vers_TS *);
+static void send_modified (const char *, const char *, Vers_TS *);
 
 /* VERS->OPTIONS specifies whether the file is binary or not.  NOTE: BEFORE
    using any other fields of the struct vers, we would need to fix
    client_process_import_file to set them up.  */
 
 static void
-send_modified( char *file, char *short_pathname, Vers_TS *vers)
+send_modified(const char *file, const char *short_pathname, Vers_TS *vers)
 {
     /* File was modified, send it.  */
     struct stat sb;
@@ -3928,7 +3929,7 @@
     struct file_info xfinfo;
     /* File name to actually use.  Might differ in case from
        finfo->file.  */
-    char *filename;
+    const char *filename;
 
     send_a_repository ("", finfo->repository, finfo->update_dir);
 
@@ -4069,10 +4070,10 @@
     return 0;
 }
 
-static void send_ignproc (char *, char *);
+static void send_ignproc (const char *, const char *);
 
 static void
-send_ignproc( char *file, char *dir )
+send_ignproc( const char *file, const char *dir )
 {
     if (ign_inhibit_server || !supported_request ("Questionable"))
     {
@@ -4089,11 +4090,11 @@
     }
 }
 
-static int send_filesdoneproc (void *, int, char *, char *, List *);
+static int send_filesdoneproc (void *, int, const char *, const char *, List 
*);
 
 static int
-send_filesdoneproc( void *callerdat, int err, char *repository,
-                    char *update_dir, List *entries )
+send_filesdoneproc( void *callerdat, int err, const char *repository,
+                    const char *update_dir, List *entries )
 {
     /* if this directory has an ignore list, process it then free it */
     if (ignlist)
@@ -4105,7 +4106,8 @@
     return (err);
 }
 
-static Dtype send_dirent_proc (void *, char *, char *, char *, List *);
+static Dtype send_dirent_proc (void *, const char *, const char *, const char 
*,
+    List *);
 
 /*
  * send_dirent_proc () is called back by the recursion processor before a
@@ -4116,8 +4118,8 @@
  *
  */
 static Dtype
-send_dirent_proc( void *callerdat, char *dir, char *repository,
-                  char *update_dir, List *entries )
+send_dirent_proc( void *callerdat, const char *dir, const char *repository,
+                  const char *update_dir, List *entries )
 {
     struct send_data *args = (struct send_data *) callerdat;
     int dir_exists;
@@ -4139,8 +4141,7 @@
      * This case will happen when checking out a module defined as
      * ``-a .''.
      */
-    cvsadm_name = xmalloc (strlen (dir) + sizeof (CVSADM) + 10);
-    sprintf (cvsadm_name, "%s/%s", dir, CVSADM);
+    (void) xasprintf (&cvsadm_name, "%s/%s", dir, CVSADM);
     dir_exists = isdir (cvsadm_name);
     free (cvsadm_name);
 
@@ -4186,7 +4187,7 @@
     return (dir_exists ? R_PROCESS : R_SKIP_ALL);
 }
 
-static int send_dirleave_proc (void *, char *, int, char *, List *);
+static int send_dirleave_proc (void *, const char *, int, const char *, List 
*);
 
 /*
  * send_dirleave_proc () is called back by the recursion code upon leaving
@@ -4195,8 +4196,8 @@
  */
 /* ARGSUSED */
 static int
-send_dirleave_proc( void *callerdat, char *dir, int err, char *update_dir,
-                    List *entries )
+send_dirleave_proc( void *callerdat, const char *dir, int err,
+    const char *update_dir, List *entries )
 {
 
     /* Delete the ignore list if it hasn't already been done.  */
@@ -4212,7 +4213,7 @@
  */
 
 void
-send_option_string( char *string )
+send_option_string( const char *string )
 {
     char *copy;
     char *p;
@@ -4391,8 +4392,8 @@
     err = start_recursion
        ( send_fileproc, send_filesdoneproc,
          send_dirent_proc, send_dirleave_proc, (void *) &args,
-         argc, argv, local, W_LOCAL, aflag, CVS_LOCK_NONE, (char *) NULL, 0,
-         (char *) NULL );
+         argc, argv, local, W_LOCAL, aflag, CVS_LOCK_NONE,
+         (const char *) NULL, 0, (const char *) NULL );
     if (err)
        exit (EXIT_FAILURE);
     if (toplevel_repos == NULL)
@@ -4629,8 +4630,8 @@
 }
 
 void
-client_notify( char *repository, char *update_dir, char *filename,
-               int notif_type, char *val )
+client_notify(const char *repository, const char *update_dir,
+             const char *filename, int notif_type, const char *val)
 {
     char buf[2];
 
Index: src/client.h
===================================================================
RCS file: /cvs/ccvs/src/client.h,v
retrieving revision 1.47
diff -u -u -r1.47 client.h
--- src/client.h        30 Sep 2003 20:17:06 -0000      1.47
+++ src/client.h        25 Oct 2003 02:17:30 -0000
@@ -67,7 +67,7 @@
 # endif /* HAVE_KERBEROS */
 
 /* Talking to the server. */
-void send_to_server (char *str, size_t len);
+void send_to_server (const char *str, size_t len);
 void read_from_server (char *buf, size_t len);
 
 /* Internal functions that handle client communication to server, etc.  */
@@ -108,13 +108,13 @@
 
 /* Send an argument to the remote server.  */
 void
-send_arg (char *string);
+send_arg (const char *string);
 
 /* Send a string of single-char options to the remote server, one by one.  */
 void
-send_option_string (char *string);
+send_option_string (const char *string);
 
-extern void send_a_repository (char *, char *, char *);
+extern void send_a_repository (const char *, const char *, const char *);
 
 #endif /* CLIENT_SUPPORT */
 
@@ -192,5 +192,6 @@
           int targc, char *targv[], char *repository, int all_files_binary,
           int modtime);
 extern void client_import_done (void);
-extern void client_notify (char *, char *, char *, int, char *);
+extern void client_notify (const char *, const char *, const char *, int,
+                          const char *);
 #endif /* CLIENT_SUPPORT */
Index: src/commit.c
===================================================================
RCS file: /cvs/ccvs/src/commit.c,v
retrieving revision 1.211
diff -u -u -r1.211 commit.c
--- src/commit.c        15 Oct 2003 18:55:06 -0000      1.211
+++ src/commit.c        25 Oct 2003 02:17:31 -0000
@@ -20,30 +20,36 @@
 #include "fileattr.h"
 #include "hardlink.h"
 
-static Dtype check_direntproc (void *callerdat, char *dir, char *repos,
-                              char *update_dir, List *entries);
+static Dtype check_direntproc (void *callerdat, const char *dir,
+                              const char *repos, const char *update_dir,
+                              List *entries);
 static int check_fileproc (void *callerdat, struct file_info *finfo);
-static int check_filesdoneproc (void *callerdat, int err, char *repos,
-                               char *update_dir, List *entries);
-static int checkaddfile (char *file, char *repository, char *tag,
-                        char *options, RCSNode **rcsnode);
-static Dtype commit_direntproc (void *callerdat, char *dir, char *repos,
-                               char *update_dir, List *entries);
-static int commit_dirleaveproc (void *callerdat, char *dir, int err,
-                               char *update_dir, List *entries);
+static int check_filesdoneproc (void *callerdat, int err, const char *repos,
+                               const char *update_dir, List *entries);
+static int checkaddfile (const char *file, const char *repository,
+                        const char *tag, char *options,
+                        RCSNode **rcsnode);
+static Dtype commit_direntproc (void *callerdat, const char *dir,
+                               const char *repos,
+                               const char *update_dir, List *entries);
+static int commit_dirleaveproc (void *callerdat, const char *dir, int err,
+                               const char *update_dir, List *entries);
 static int commit_fileproc (void *callerdat, struct file_info *finfo);
-static int commit_filesdoneproc (void *callerdat, int err, char *repository,
-                                char *update_dir, List *entries);
-static int finaladd (struct file_info *finfo, char *revision, char *tag,
-                    char *options);
+static int commit_filesdoneproc (void *callerdat, int err,
+                                const char *repository,
+                                const char *update_dir, List *entries);
+static int finaladd (struct file_info *finfo, const char *revision,
+                    const char *tag, char *options);
 static int findmaxrev (Node * p, void *closure);
-static int lock_RCS (char *user, RCSNode *rcs, char *rev, char *repository);
+static int lock_RCS (const char *user, RCSNode *rcs, const char *rev,
+    const char *repository);
 static int precommit_list_proc (Node * p, void *closure);
-static int precommit_proc (char *repository, char *filter, void *closure);
-static int remove_file (struct file_info *finfo, char *tag,
-                       char *message);
+static int precommit_proc (const char *repository, const char *filter,
+                          void *closure);
+static int remove_file (struct file_info *finfo, const char *tag,
+                       const char *message);
 static void fixaddfile (const char *rcs);
-static void fixbranch (RCSNode *, char *branch);
+static void fixbranch (RCSNode *, const char *branch);
 static void unlockrcs (RCSNode *rcs);
 static void ci_delproc (Node *p);
 static void masterlist_delproc (Node *p);
@@ -113,19 +119,20 @@
     /* Only good within functions called from the filesdoneproc.  Stores
        the repository (pointer into storage managed by the recursion
        processor.  */
-    char *repository;
+    const char *repository;
 
     /* Non-zero if we should force the commit.  This is enabled by
        either -f or -r options, unlike force_ci which is just -f.  */
     int force;
 };
 
-static Dtype find_dirent_proc (void *callerdat, char *dir,
-                                     char *repository, char *update_dir,
-                                     List *entries);
+static Dtype find_dirent_proc (void *callerdat, const char *dir,
+                              const char *repository, const char *update_dir,
+                              List *entries);
 
 static Dtype
-find_dirent_proc (void *callerdat, char *dir, char *repository, char 
*update_dir, List *entries)
+find_dirent_proc (void *callerdat, const char *dir, const char *repository,
+    const char *update_dir, List *entries)
 {
     struct find_data *find_data = (struct find_data *)callerdat;
 
@@ -152,10 +159,10 @@
    it along as an argument.  */
 static struct find_data *find_data_static;
 
-static void find_ignproc (char *, char *);
+static void find_ignproc (const char *, const char *);
 
 static void
-find_ignproc (char *file, char *dir)
+find_ignproc (const char *file, const char *dir)
 {
     struct question *p;
 
@@ -167,12 +174,12 @@
     find_data_static->questionables = p;
 }
 
-static int find_filesdoneproc (void *callerdat, int err,
-                                     char *repository, char *update_dir,
-                                     List *entries);
+static int find_filesdoneproc (void *callerdat, int err, const char 
*repository,
+                              const char *update_dir, List *entries);
 
 static int
-find_filesdoneproc (void *callerdat, int err, char *repository, char 
*update_dir, List *entries)
+find_filesdoneproc (void *callerdat, int err, const char *repository,
+    const char *update_dir, List *entries)
 {
     struct find_data *find_data = (struct find_data *)callerdat;
     find_data->repository = repository;
@@ -444,7 +451,7 @@
              find_dirent_proc, (DIRLEAVEPROC) NULL,
              (void *) &find_args,
              argc, argv, local, W_LOCAL, 0, CVS_LOCK_NONE,
-             (char *) NULL, 0, (char *) NULL );
+             (const char *) NULL, 0, (const char *) NULL );
        if (err)
            error (1, 0, "correct above errors first!");
 
@@ -637,7 +644,7 @@
            ( commit_fileproc, commit_filesdoneproc,
              commit_direntproc, commit_dirleaveproc, NULL,
              argc, argv, local, W_LOCAL, aflag, CVS_LOCK_NONE,
-             (char *) NULL, 1, (char *) NULL );
+             (const char *) NULL, 1, (const char *) NULL );
 
     /*
      * Unlock all the dirs and clean up
@@ -752,7 +759,7 @@
 check_fileproc (void *callerdat, struct file_info *finfo)
 {
     Ctype status;
-    char *xdir;
+    const char *xdir;
     Node *p;
     List *ulist, *cilist;
     Vers_TS *vers;
@@ -975,9 +982,8 @@
                struct hardlink_info *hlinfo;
 
                /* Get the full pathname of the current file. */
-               fullpath = xmalloc (strlen(working_dir) +
-                                   strlen(finfo->fullname) + 2);
-               sprintf (fullpath, "%s/%s", working_dir, finfo->fullname);
+               (void ) xasprintf (&fullpath, "%s/%s", working_dir,
+                   finfo->fullname);
 
                /* To permit following links in subdirectories, files
                    are keyed on finfo->fullname, not on finfo->name. */
@@ -1024,7 +1030,8 @@
  */
 /* ARGSUSED */
 static Dtype
-check_direntproc (void *callerdat, char *dir, char *repos, char *update_dir, 
List *entries)
+check_direntproc (void *callerdat, const char *dir, const char *repos,
+    const char *update_dir, List *entries)
 {
     if (!isdir (dir))
        return (R_SKIP_ALL);
@@ -1057,7 +1064,7 @@
  * Callback proc for pre-commit checking
  */
 static int
-precommit_proc(char *repository, char *filter, void *closure)
+precommit_proc(const char *repository, const char *filter, void *closure)
 {
     /* see if the filter is there, only if it's a full path */
     if (isabsolute (filter))
@@ -1091,7 +1098,8 @@
  */
 /* ARGSUSED */
 static int
-check_filesdoneproc (void *callerdat, int err, char *repos, char *update_dir, 
List *entries)
+check_filesdoneproc (void *callerdat, int err, const char *repos,
+    const char *update_dir, List *entries)
 {
     int n;
     Node *p;
@@ -1259,8 +1267,7 @@
            }
            if (maxrev == 0)
                maxrev = 1;
-           xrev = xmalloc (20);
-           (void) sprintf (xrev, "%d", maxrev);
+           (void) xasprintf (&xrev, "%d", maxrev);
        }
 
        /* XXX - an added file with symbolic -r should add tag as well */
@@ -1350,7 +1357,8 @@
  */
 /* ARGSUSED */
 static int
-commit_filesdoneproc (void *callerdat, int err, char *repository, char 
*update_dir, List *entries)
+commit_filesdoneproc (void *callerdat, int err, const char *repository,
+    const char *update_dir, List *entries)
 {
     Node *p;
     List *ulist;
@@ -1368,7 +1376,7 @@
 
     /* Build the administrative files if necessary.  */
     {
-       char *p;
+       const char *p;
 
        if (strncmp (current_parsed_root->directory, repository,
                     strlen (current_parsed_root->directory)) != 0)
@@ -1417,7 +1425,8 @@
  */
 /* ARGSUSED */
 static Dtype
-commit_direntproc (void *callerdat, char *dir, char *repos, char *update_dir, 
List *entries)
+commit_direntproc (void *callerdat, const char *dir, const char *repos,
+    const char *update_dir, List *entries)
 {
     Node *p;
     List *ulist;
@@ -1456,7 +1465,8 @@
  */
 /* ARGSUSED */
 static int
-commit_dirleaveproc (void *callerdat, char *dir, int err, char *update_dir, 
List *entries)
+commit_dirleaveproc (void *callerdat, const char *dir, int err,
+    const char *update_dir, List *entries)
 {
     /* update the per-directory tag info */
     /* FIXME?  Why?  The "commit examples" node of cvs.texinfo briefly
@@ -1500,7 +1510,7 @@
    Return value is 0 on success, or >0 on error (in which case we have
    printed an error message).  */
 static int
-remove_file (struct file_info *finfo, char *tag, char *message)
+remove_file (struct file_info *finfo, const char *tag, const char *message)
 {
     int retcode;
 
@@ -1654,16 +1664,16 @@
  * Do the actual checkin for added files
  */
 static int
-finaladd (struct file_info *finfo, char *rev, char *tag, char *options)
+finaladd (struct file_info *finfo, const char *rev, const char *tag,
+    char *options)
 {
     int ret;
 
     ret = Checkin ('A', finfo, rev, tag, options, saved_message);
     if (ret == 0)
     {
-       char *tmp = xmalloc (strlen (finfo->file) + sizeof (CVSADM)
-                            + sizeof (CVSEXT_LOG) + 10);
-       (void) sprintf (tmp, "%s/%s%s", CVSADM, finfo->file, CVSEXT_LOG);
+       char *tmp;
+       (void) xasprintf (&tmp, "%s/%s%s", CVSADM, finfo->file, CVSEXT_LOG);
        if (unlink_file (tmp) < 0
            && !existence_error (errno))
            error (0, errno, "cannot remove %s", tmp);
@@ -1725,7 +1735,7 @@
  * put the branch back on an rcs file
  */
 static void
-fixbranch (RCSNode *rcs, char *branch)
+fixbranch (RCSNode *rcs, const char *branch)
 {
     int retcode;
 
@@ -1767,8 +1777,8 @@
  */
 
 static int
-checkaddfile (char *file, char *repository, char *tag, char *options,
-             RCSNode **rcsnode)
+checkaddfile (const char *file, const char *repository, const char *tag,
+    char *options, RCSNode **rcsnode)
 {
     RCSNode *rcs;
     char *fname;
@@ -1800,17 +1810,13 @@
        if ( adding_on_branch )
        {
            mode_t omask;
-           rcsname = xmalloc (strlen (repository)
-                              + sizeof (CVSATTIC)
-                              + strlen (file)
-                              + sizeof (RCSEXT)
-                              + 3);
-           (void) sprintf (rcsname, "%s/%s", repository, CVSATTIC);
+           (void) xasprintf (&rcsname, "%s/%s", repository, CVSATTIC);
            omask = umask ( cvsumask );
            if (CVS_MKDIR (rcsname, 0777 ) != 0 && errno != EEXIST)
                error (1, errno, "cannot make directory `%s'", rcsname);
+           free (rcsname);
            (void) umask ( omask );
-           (void) sprintf (rcsname,
+           (void) xasprintf (&rcsname,
                            "%s/%s/%s%s",
                            repository,
                            CVSATTIC,
@@ -1819,11 +1825,7 @@
        }
        else
        {
-           rcsname = xmalloc (strlen (repository)
-                              + strlen (file)
-                              + sizeof (RCSEXT)
-                              + 2);
-           (void) sprintf (rcsname,
+           (void) xasprintf (&rcsname,
                            "%s/%s%s",
                            repository,
                            file,
@@ -1832,9 +1834,7 @@
 
        /* this is the first time we have ever seen this file; create
           an RCS file.  */
-       fname = xmalloc (strlen (file) + sizeof (CVSADM)
-                        + sizeof (CVSEXT_LOG) + 10);
-       (void) sprintf (fname, "%s/%s%s", CVSADM, file, CVSEXT_LOG);
+       (void) xasprintf (&fname, "%s/%s%s", CVSADM, file, CVSEXT_LOG);
        /* If the file does not exist, no big deal.  In particular, the
           server does not (yet at least) create CVSEXT_LOG files.  */
        if (isfile (fname))
@@ -1947,9 +1947,7 @@
            int retcode;
 
            /* move the new file out of the way. */
-           fname = xmalloc (strlen (file) + sizeof (CVSADM)
-                            + sizeof (CVSPREFIX) + 10);
-           (void) sprintf (fname, "%s/%s%s", CVSADM, CVSPREFIX, file);
+           (void) xasprintf (&fname, "%s/%s%s", CVSADM, CVSPREFIX, file);
            rename_file (file, fname);
 
            /* Create empty FILE.  Can't use copy_file with a DEVNULL
@@ -1960,9 +1958,8 @@
            if (fclose (fp) < 0)
                error (0, errno, "cannot close %s", file);
 
-           tmp = xmalloc (strlen (file) + strlen (tag) + 80);
            /* commit a dead revision. */
-           (void) sprintf (tmp, "file %s was initially added on branch %s.",
+           (void) xasprintf (&tmp, "file %s was initially added on branch %s.",
                            file, tag);
            retcode = RCS_checkin (rcs, NULL, tmp, NULL,
                                   RCS_FLAGS_DEAD | RCS_FLAGS_QUIET);
@@ -2074,7 +2071,8 @@
  * put the branch back as the head if there are any errors.
  */
 static int
-lock_RCS (char *user, RCSNode *rcs, char *rev, char *repository)
+lock_RCS (const char *user, RCSNode *rcs, const char *rev,
+    const char *repository)
 {
     char *branch = NULL;
     int err = 0;
Index: src/create_adm.c
===================================================================
RCS file: /cvs/ccvs/src/create_adm.c,v
retrieving revision 1.43
diff -u -u -r1.43 create_adm.c
--- src/create_adm.c    23 Jul 2003 20:42:25 -0000      1.43
+++ src/create_adm.c    25 Oct 2003 02:17:31 -0000
@@ -22,7 +22,7 @@
    don't print warnings; all errors are fatal then.  */
 
 int
-Create_Admin (char *dir, char *update_dir, char *repository, char *tag, char 
*date, int nonbranch, int warn, int dotemplate)
+Create_Admin (const char *dir, const char *update_dir, const char *repository, 
const char *tag, const char *date, int nonbranch, int warn, int dotemplate)
 {
     FILE *fout;
     char *cp;
@@ -36,13 +36,13 @@
     if (noexec)
        return 0;
 
-    tmp = xmalloc (strlen (dir) + 100);
-    (void) sprintf (tmp, "%s/%s", dir, CVSADM);
+    (void) xasprintf (&tmp, "%s/%s", dir, CVSADM);
     if (isfile (tmp))
        error (1, 0, "there is a version in %s already", update_dir);
 
     if (CVS_MKDIR (tmp, 0777) < 0)
     {
+       free (tmp);
        /* We want to print out the entire update_dir, since a lot of
           our code calls this function with dir == "." or dir ==
           NULL.  I hope that gives enough information in cases like
@@ -58,21 +58,21 @@
               the warning at least we let them know what is going on.  */
            error (0, errno, "warning: cannot make directory %s in %s",
                   CVSADM, update_dir);
-           free (tmp);
            return 1;
        }
        else
            error (1, errno, "cannot make directory %s in %s",
                   CVSADM, update_dir);
     }
+    free (tmp);
 
     /* record the current cvs root for later use */
 
     Create_Root (dir, current_parsed_root->original);
     if (dir != NULL)
-       (void) sprintf (tmp, "%s/%s", dir, CVSADM_REP);
+       (void) xasprintf (&tmp, "%s/%s", dir, CVSADM_REP);
     else
-       (void) strcpy (tmp, CVSADM_REP);
+       tmp = xstrdup (CVSADM_REP);
     fout = CVS_FOPEN (tmp, "w+");
     if (fout == NULL)
     {
@@ -103,9 +103,9 @@
      * the leading CVSroot argument.
      */
     {
-    char *path = xmalloc (strlen (current_parsed_root->directory) + 2);
+    char *path;
 
-    (void) sprintf (path, "%s/", current_parsed_root->directory);
+    (void) xasprintf (&path, "%s/", current_parsed_root->directory);
     if (strncmp (cp, path, strlen (path)) == 0)
        cp += strlen (path);
     free (path);
@@ -127,10 +127,11 @@
     }
 
     /* now, do the Entries file */
+    free (tmp);
     if (dir != NULL)
-       (void) sprintf (tmp, "%s/%s", dir, CVSADM_ENT);
+       (void) xasprintf (&tmp, "%s/%s", dir, CVSADM_ENT);
     else
-       (void) strcpy (tmp, CVSADM_ENT);
+       tmp = xstrdup (CVSADM_ENT);
     fout = CVS_FOPEN (tmp, "w+");
     if (fout == NULL)
     {
Index: src/cvs.h
===================================================================
RCS file: /cvs/ccvs/src/cvs.h,v
retrieving revision 1.273
diff -u -u -r1.273 cvs.h
--- src/cvs.h   9 Oct 2003 19:01:27 -0000       1.273
+++ src/cvs.h   25 Oct 2003 02:17:31 -0000
@@ -364,7 +364,7 @@
 extern cvsroot_t *current_parsed_root;
 
 char *emptydir_name (void);
-int safe_location (char *);
+int safe_location (const char *);
 
 extern int trace;              /* Show all commands */
 extern int noexec;             /* Don't modify disk anywhere */
@@ -389,7 +389,8 @@
 
 /* Externs that are included directly in the CVS sources */
 
-int RCS_merge (RCSNode *, char *, char *, char *, char *, char *);
+int RCS_merge (RCSNode *, const char *, const char *, const char *,
+    const char *, const char *);
 /* Flags used by RCS_* functions.  See the description of the individual
    functions for which flags mean what for each function.  */
 #define RCS_FLAGS_FORCE 1
@@ -399,51 +400,52 @@
 #define RCS_FLAGS_KEEPFILE 16
 
 int RCS_exec_rcsdiff (RCSNode *rcsfile,
-                      char *opts, char *options,
-                      char *rev1, char *rev1_cache, char *rev2,
-                      char *label1, char *label2,
-                      char *workfile);
-int diff_exec (char *file1, char *file2,
-               char *label1, char *label2,
-               char *options, char *out);
+                      const char *opts, const char *options,
+                      const char *rev1, const char *rev1_cache,
+                     const char *rev2,
+                      const char *label1, const char *label2,
+                      const char *workfile);
+int diff_exec (const char *file1, const char *file2,
+               const char *label1, const char *label2,
+               const char *options, const char *out);
 
 
 #include "error.h"
 
 DBM *open_module (void);
 FILE *open_file (const char *, const char *);
-List *Find_Directories (char *repository, int which, List *entries);
+List *Find_Directories (const char *repository, int which, List *entries);
 void Entries_Close (List *entries);
-List *Entries_Open (int aflag, char *update_dir);
+List *Entries_Open (int aflag, const char *update_dir);
 void Subdirs_Known (List *entries);
 void Subdir_Register (List *, const char *, const char *);
 void Subdir_Deregister (List *, const char *, const char *);
 
-char *Make_Date (char *rawdate);
+char *Make_Date (const char *rawdate);
 char *date_from_time_t (time_t);
 void date_to_internet (char *, const char *);
 void date_to_tm (struct tm *, const char *);
 void tm_to_internet (char *, const struct tm *);
 
-char *Name_Repository (char *dir, char *update_dir);
-char *Short_Repository (char *repository);
+char *Name_Repository (const char *dir, const char *update_dir);
+const char *Short_Repository (const char *repository);
 void Sanitize_Repository_Name (char *repository);
 
-char *Name_Root (char *dir, char *update_dir);
+char *Name_Root (const char *dir, const char *update_dir);
 void free_cvsroot_t (cvsroot_t *root_in);
 cvsroot_t *parse_cvsroot (const char *root)
        __attribute__ ((__malloc__));
 cvsroot_t *local_cvsroot (const char *dir)
        __attribute__ ((__malloc__));
-void Create_Root (char *dir, char *rootdir);
-void root_allow_add (char *);
+void Create_Root (const char *dir, const char *rootdir);
+void root_allow_add (const char *);
 void root_allow_free (void);
-int root_allow_ok (char *);
+int root_allow_ok (const char *);
 
 char *gca (const char *rev1, const char *rev2);
 void check_numeric (const char *, int, char **);
 char *getcaller (void);
-char *time_stamp (char *file);
+char *time_stamp (const char *file);
 
 void *xmalloc (size_t bytes)
        __attribute__((__malloc__));
@@ -453,13 +455,15 @@
 void xrealloc_and_strcat (char **, size_t *, const char *);
 char *xstrdup (const char *str)
        __attribute__ ((__malloc__));
+int  xasprintf (char **, const char *, ...)
+       __attribute__ ((__format__(__printf__,2,3)));
 int strip_trailing_newlines (char *str);
-int pathname_levels (char *path);
+int pathname_levels (const char *path);
 
-typedef        int (*CALLPROC) ( char *repository, char *value, void *closure 
);
-int Parse_Info (char *infofile, char *repository, CALLPROC callproc,
+typedef        int (*CALLPROC) ( const char *repository, const char *value, 
void *closure );
+int Parse_Info (const char *infofile, const char *repository, CALLPROC 
callproc,
                 int opt, void *closure);
-int parse_config (char *);
+int parse_config (const char *);
 
 typedef        RETSIGTYPE (*SIGCLEANUPPROC)    ();
 int SIG_register (int sig, SIGCLEANUPPROC sigcleanup);
@@ -475,7 +479,7 @@
 char *xreadlink (const char *link);
 #endif /* HAVE_READLINK */
 char *xresolvepath (const char *path);
-char *last_component (char *path);
+char *last_component (const char *path);
 char *get_homedir (void);
 char *strcat_filename_onto_homedir (const char *, const char *);
 char *cvs_temp_name (void);
@@ -490,15 +494,15 @@
 int xcmp (const char *file1, const char *file2);
 int yesno (void);
 void *valloc (size_t bytes);
-time_t get_date (char *date, struct timeb *now);
-int Create_Admin (char *dir, char *update_dir,
-                  char *repository, char *tag, char *date,
+time_t get_date (const char *date, struct timeb *now);
+int Create_Admin (const char *dir, const char *update_dir,
+                  const char *repository, const char *tag, const char *date,
                   int nonbranch, int warn, int dotemplate);
-int expand_at_signs (char *, off_t, FILE *);
+int expand_at_signs (const char *, off_t, FILE *);
 
 /* Locking subsystem (implemented in lock.c).  */
 
-int Reader_Lock (char *xrepository);
+int Reader_Lock (const char *xrepository);
 void Lock_Cleanup (void);
 
 /* Writelock an entire subtree, well the part specified by ARGC, ARGV, LOCAL,
@@ -507,7 +511,7 @@
                                 int aflag);
 
 /* See lock.c for description.  */
-void lock_dir_for_write (char *);
+void lock_dir_for_write (const char *);
 
 /* LockDir setting from CVSROOT/config.  */
 extern char *lock_dir;
@@ -515,36 +519,37 @@
 /* AllowedAdminOptions setting from CVSROOT/config.  */
 extern char *UserAdminOptions;
 
-void Scratch_Entry (List * list, char *fname);
+void Scratch_Entry (List * list, const char *fname);
 void ParseTag (char **tagp, char **datep, int *nonbranchp);
-void WriteTag (char *dir, char *tag, char *date, int nonbranch,
-                     char *update_dir, char *repository);
-void WriteTemplate (char *update_dir, int dotemplate,
-                          char *repository);
+void WriteTag (const char *dir, const char *tag, const char *date,
+               int nonbranch, const char *update_dir, const char *repository);
+void WriteTemplate (const char *update_dir, int dotemplate,
+                          const char *repository);
 void cat_module (int status);
-void check_entries (char *dir);
+void check_entries (const char *dir);
 void close_module (DBM * db);
 void copy_file (const char *from, const char *to);
-void fperrmsg (FILE * fp, int status, int errnum, char *message,...);
+void fperrmsg (FILE * fp, int status, int errnum, const char *message,...);
 void free_names (int *pargc, char *argv[]);
 
-int ign_name (char *name);
-void ign_add (char *ign, int hold);
-void ign_add_file (char *file, int hold);
+int ign_name (const char *name);
+void ign_add (const char *ign, int hold);
+void ign_add_file (const char *file, int hold);
 void ign_setup (void);
-void ign_dir_add (char *name);
-int ignore_directory (char *name);
-typedef void (*Ignore_proc) (char *, char *);
-void ignore_files (List *, List *, char *, Ignore_proc);
+void ign_dir_add (const char *name);
+int ignore_directory (const char *name);
+typedef void (*Ignore_proc) (const char *, const char *);
+void ignore_files (List *, List *, const char *, Ignore_proc);
 extern int ign_inhibit_server;
 extern int ign_case;
 
 #include "update.h"
 
-void line2argv (int *pargc, char ***argv, char *line, char *sepchars);
+void line2argv (int *pargc, char ***argv, const char *line,
+               const char *sepchars);
 void make_directories (const char *name);
 void make_directory (const char *name);
-int mkdir_if_needed (char *name);
+int mkdir_if_needed (const char *name);
 void rename_file (const char *from, const char *to);
 /* Expand wildcards in each element of (ARGC,ARGV).  This is according to the
    files which exist in the current directory, and accordingly to OS-specific
@@ -561,7 +566,7 @@
 
 #ifdef SERVER_SUPPORT
 int cvs_casecmp (const char *, const char *);
-int fopen_case (char *, char *, FILE **, char **);
+int fopen_case (const char *, const char *, FILE **, char **);
 #endif
 
 /* exithandle.c */
@@ -571,45 +576,46 @@
 void strip_trailing_slashes (char *path);
 void update_delproc (Node * p);
 void usage (const char *const *cpp);
-void xchmod (char *fname, int writable);
+void xchmod (const char *fname, int writable);
 char *xgetwd (void);
-List *Find_Names (char *repository, int which, int aflag,
+List *Find_Names (const char *repository, int which, int aflag,
                  List ** optentries);
-void Register (List * list, char *fname, char *vn, char *ts,
-              char *options, char *tag, char *date, char *ts_conflict);
-void Update_Logfile (char *repository, char *xmessage, FILE * xlogfp,
-                    List * xchanges);
-void do_editor (char *dir, char **messagep,
-                     char *repository, List * changes);
-
-void do_verify (char **messagep, char *repository);
-
-typedef        int (*CALLBACKPROC)     (int argc, char *argv[], char *where,
-       char *mwhere, char *mfile, int shorten, int local_specified,
-       char *omodule, char *msg);
+void Register (List * list, const char *fname, const char *vn, const char *ts,
+              const char *options, const char *tag, const char *date,
+              const char *ts_conflict);
+void Update_Logfile (const char *repository, const char *xmessage,
+                    FILE *xlogfp, List *xchanges);
+void do_editor (const char *dir, char **messagep,
+                     const char *repository, List * changes);
+
+void do_verify (char **messagep, const char *repository);
+
+typedef        int (*CALLBACKPROC)     (int argc, char *argv[], const char 
*where,
+       const char *mwhere, const char *mfile, int shorten, int local_specified,
+       const char *omodule, const char *msg);
 
 /* This is the structure that the recursion processor passes to the
    fileproc to tell it about a particular file.  */
 struct file_info
 {
     /* Name of the file, without any directory component.  */
-    char *file;
+    const char *file;
 
     /* Name of the directory we are in, relative to the directory in
        which this command was issued.  We have cd'd to this directory
        (either in the working directory or in the repository, depending
        on which sort of recursion we are doing).  If we are in the directory
        in which the command was issued, this is "".  */
-    char *update_dir;
+    const char *update_dir;
 
     /* update_dir and file put together, with a slash between them as
        necessary.  This is the proper way to refer to the file in user
        messages.  */
-    char *fullname;
+    const char *fullname;
 
     /* Name of the directory corresponding to the repository which contains
        this file.  */
-    char *repository;
+    const char *repository;
 
     /* The pre-parsed entries for this directory.  */
     List *entries;
@@ -619,35 +625,36 @@
 
 typedef        int (*FILEPROC) (void *callerdat, struct file_info *finfo);
 typedef        int (*FILESDONEPROC) (void *callerdat, int err,
-                                    char *repository, char *update_dir,
+                                    const char *repository,
+                                    const char *update_dir,
                                     List *entries);
-typedef        Dtype (*DIRENTPROC) (void *callerdat, char *dir,
-                                   char *repos, char *update_dir,
+typedef        Dtype (*DIRENTPROC) (void *callerdat, const char *dir,
+                                   const char *repos, const char *update_dir,
                                    List *entries);
-typedef        int (*DIRLEAVEPROC) (void *callerdat, char *dir, int err,
-                                   char *update_dir, List *entries);
+typedef        int (*DIRLEAVEPROC) (void *callerdat, const char *dir, int err,
+                                   const char *update_dir, List *entries);
 
-int mkmodules (char *dir);
+int mkmodules (const char *dir);
 int init (int argc, char **argv);
 
-int do_module (DBM * db, char *mname, enum mtype m_type, char *msg,
-               CALLBACKPROC callback_proc, char *where, int shorten,
+int do_module (DBM * db, const char *mname, enum mtype m_type, const char *msg,
+               CALLBACKPROC callback_proc, const char *where, int shorten,
                int local_specified, int run_module_prog, int build_dirs,
-               char *extra_arg);
-void history_write (int type, char *update_dir, char *revs, char *name,
-                   char *repository);
+               const char *extra_arg);
+void history_write (int type, const char *update_dir, const char *revs,
+                   const char *name, const char *repository);
 int start_recursion (FILEPROC fileproc, FILESDONEPROC filesdoneproc,
                     DIRENTPROC direntproc, DIRLEAVEPROC dirleaveproc,
                     void *callerdat,
                     int argc, char *argv[], int local, int which,
-                    int afag, int locktype, char *update_preload,
-                    int dosrcsi, char *repository);
+                    int afag, int locktype, const char *update_preload,
+                    int dosrcsi, const char *repository);
 void SIG_beginCrSect (void);
 void SIG_endCrSect (void);
 int SIG_inCrSect (void);
-void read_cvsrc (int *argc, char ***argv, char *cmdname);
+void read_cvsrc (int *argc, char ***argv, const char *cmdname);
 
-char *make_message_rcsvalid (char *message);
+char *make_message_rcsvalid (const char *message);
 int file_has_conflict (const struct file_info *,
                        const char *ts_conflict);
 int file_has_markers (const struct file_info *);
@@ -750,20 +757,20 @@
 };
 typedef struct vers_ts Vers_TS;
 
-Vers_TS *Version_TS (struct file_info *finfo, char *options, char *tag,
-                           char *date, int force_tag_match,
+Vers_TS *Version_TS (struct file_info *finfo, const char *options,
+                    const char *tag, const char *date, int force_tag_match,
                            int set_time);
 void freevers_ts (Vers_TS ** versp);
 
 /* Miscellaneous CVS infrastructure which layers on top of the recursion
    processor (for example, needs struct file_info).  */
 
-int Checkin (int type, struct file_info *finfo, char *rev,
-            char *tag, char *options, char *message);
+int Checkin (int type, struct file_info *finfo, const char *rev,
+            const char *tag, const char *options, const char *message);
 int No_Difference (struct file_info *finfo, Vers_TS *vers);
 /* TODO: can the finfo argument to special_file_mismatch be changed? -twp */
 int special_file_mismatch (struct file_info *finfo,
-                                 char *rev1, char *rev2);
+                                 const char *rev1, const char *rev2);
 
 /* CVSADM_BASEREV stuff, from entries.c.  */
 char *base_get (struct file_info *);
@@ -791,8 +798,10 @@
 };
 typedef enum classify_type Ctype;
 
-Ctype Classify_File (struct file_info *finfo, char *tag, char *date, char 
*options,
-      int force_tag_match, int aflag, Vers_TS **versp, int pipeout);
+Ctype Classify_File (struct file_info *finfo, const char *tag,
+                    const char *date, const char *options,
+                    int force_tag_match, int aflag, Vers_TS **versp,
+                    int pipeout);
 
 /*
  * structure used for list nodes passed to Update_Logfile() and
@@ -833,12 +842,12 @@
 #endif /* SERVER_SUPPORT || CLIENT_SUPPORT */
 
 /* Pathname expansion */
-char *expand_path (char *name, char *file, int line);
+char *expand_path (const char *name, const char *file, int line);
 
 /* User variables.  */
 extern List *variable_list;
 
-void variable_set (char *nameval);
+void variable_set (const char *nameval);
 
 int watch (int argc, char **argv);
 int edit (int argc, char **argv);
@@ -875,11 +884,11 @@
 int cvstag (int argc, char **argv);
 int version (int argc, char **argv);
 
-unsigned long int lookup_command_attribute (char *);
+unsigned long int lookup_command_attribute (const char *);
 
 #if defined(AUTH_CLIENT_SUPPORT) || defined(AUTH_SERVER_SUPPORT)
-char *scramble (char *str);
-char *descramble (char *str);
+char *scramble (const char *str);
+char *descramble (const char *str);
 #endif /* AUTH_CLIENT_SUPPORT || AUTH_SERVER_SUPPORT */
 
 #ifdef AUTH_CLIENT_SUPPORT
@@ -892,23 +901,29 @@
        __attribute__ ((__malloc__));
 #endif /* AUTH_CLIENT_SUPPORT */
 
-void tag_check_valid (char *, int, char **, int, int, char *);
-void tag_check_valid_join (char *, int, char **, int, int,
-                           char *);
+void tag_check_valid (const char *, int, char **, int, int, const char *);
+void tag_check_valid_join (const char *, int, char **, int, int,
+                           const char *);
 
 #include "server.h"
 
 /* From server.c and documented there.  */
 void cvs_output (const char *, size_t);
-void cvs_output_binary (char *, size_t);
+void cvs_output_binary (const char *, size_t);
 void cvs_outerr (const char *, size_t);
 void cvs_flusherr (void);
 void cvs_flushout (void);
-void cvs_output_tagged (char *, char *);
+void cvs_output_tagged (const char *, const char *);
 
 /* The trace function from subr.c */
 void cvs_trace (int level, const char *fmt, ...)
   __attribute__ ((__format__ (__printf__, 2, 3)));
+
+int get_repository (char **repository, char **where, const char *mfile,
+    int *argc, char ***argv, char **myargv);
+void handle_mfile (char *repository, char *where, const char *mfile,
+    int *argc, char ***argv, char **myargv);
+
 #define TRACE cvs_trace
 /* Trace levels:
  *
Index: src/cvsrc.c
===================================================================
RCS file: /cvs/ccvs/src/cvsrc.c,v
retrieving revision 1.25
diff -u -u -r1.25 cvsrc.c
--- src/cvsrc.c 23 Jul 2003 20:42:25 -0000      1.25
+++ src/cvsrc.c 25 Oct 2003 02:17:31 -0000
@@ -27,7 +27,7 @@
    options, and update *ARGC and *ARGV accordingly.  */
 
 void
-read_cvsrc (int *argc, char ***argv, char *cmdname)
+read_cvsrc (int *argc, char ***argv, const char *cmdname)
 {
     char *homedir;
     char *homeinit;
Index: src/diff.c
===================================================================
RCS file: /cvs/ccvs/src/diff.c,v
retrieving revision 1.106
diff -u -u -r1.106 diff.c
--- src/diff.c  29 Sep 2003 18:49:24 -0000      1.106
+++ src/diff.c  25 Oct 2003 02:17:32 -0000
@@ -25,14 +25,14 @@
     DIFF_SAME
 };
 
-static Dtype diff_dirproc (void *callerdat, char *dir,
-                                 char *pos_repos, char *update_dir,
+static Dtype diff_dirproc (void *callerdat, const char *dir,
+                                 const char *pos_repos, const char *update_dir,
                                  List *entries);
 static int diff_filesdoneproc (void *callerdat, int err,
-                                     char *repos, char *update_dir,
+                                     const char *repos, const char *update_dir,
                                      List *entries);
-static int diff_dirleaveproc (void *callerdat, char *dir,
-                                    int err, char *update_dir,
+static int diff_dirleaveproc (void *callerdat, const char *dir,
+                                    int err, const char *update_dir,
                                     List *entries);
 static enum diff_file diff_file_nodiff ( struct file_info *finfo,
                                               Vers_TS *vers,
@@ -429,7 +429,8 @@
     err = start_recursion
            ( diff_fileproc, diff_filesdoneproc, diff_dirproc,
              diff_dirleaveproc, NULL, argc, argv, local,
-             which, 0, CVS_LOCK_READ, (char *) NULL, 1, (char *) NULL );
+             which, 0, CVS_LOCK_READ, (const char *) NULL, 1,
+             (const char *) NULL );
 
     /* clean up */
     free (options);
@@ -587,11 +588,7 @@
     if( tocvsPath != NULL )
     {
        /* Backup the current version of the file to CVS/,,filename */
-       fname = xmalloc (strlen (finfo->file)
-                        + sizeof CVSADM
-                        + sizeof CVSPREFIX
-                        + 10);
-       sprintf(fname,"%s/%s%s",CVSADM, CVSPREFIX, finfo->file);
+       (void) xasprintf(&fname,"%s/%s%s",CVSADM, CVSPREFIX, finfo->file);
        if (unlink_file_dir (fname) < 0)
            if (! existence_error (errno))
                error (1, errno, "cannot remove %s", fname);
@@ -758,7 +755,8 @@
  */
 /* ARGSUSED */
 static Dtype
-diff_dirproc (void *callerdat, char *dir, char *pos_repos, char *update_dir, 
List *entries)
+diff_dirproc (void *callerdat, const char *dir, const char *pos_repos,
+    const char *update_dir, List *entries)
 {
     /* XXX - check for dirs we don't want to process??? */
 
@@ -776,7 +774,8 @@
  */
 /* ARGSUSED */
 static int
-diff_filesdoneproc (void *callerdat, int err, char *repos, char *update_dir, 
List *entries)
+diff_filesdoneproc (void *callerdat, int err, const char *repos,
+    const char *update_dir, List *entries)
 {
     return (diff_errors);
 }
@@ -786,7 +785,8 @@
  */
 /* ARGSUSED */
 static int
-diff_dirleaveproc (void *callerdat, char *dir, int err, char *update_dir, List 
*entries)
+diff_dirleaveproc (void *callerdat, const char *dir, int err,
+    const char *update_dir, List *entries)
 {
     return (diff_errors);
 }
Index: src/edit.c
===================================================================
RCS file: /cvs/ccvs/src/edit.c,v
retrieving revision 1.63
diff -u -u -r1.63 edit.c
--- src/edit.c  23 Jul 2003 20:42:25 -0000      1.63
+++ src/edit.c  25 Oct 2003 02:17:32 -0000
@@ -34,10 +34,12 @@
     return 0;
 }
 
-static int onoff_filesdoneproc (void *, int, char *, char *, List *);
+static int onoff_filesdoneproc (void *, int, const char *, const char *,
+                               List *);
 
 static int
-onoff_filesdoneproc (void *callerdat, int err, char *repository, char 
*update_dir, List *entries)
+onoff_filesdoneproc (void *callerdat, int err, const char *repository,
+    const char *update_dir, List *entries)
 {
     if (setting_default)
        fileattr_set (NULL, "_watched", turning_on ? "" : NULL);
@@ -96,7 +98,7 @@
        ( onoff_fileproc, onoff_filesdoneproc,
          (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL,
          argc, argv, local, W_LOCAL, 0, CVS_LOCK_NONE,
-         (char *) NULL, 0, (char *) NULL );
+         (const char *) NULL, 0, (const char *) NULL );
 
     Lock_Cleanup ();
     return err;
@@ -315,10 +317,7 @@
        trying to create the output file fails.  But copy_file isn't
        set up to facilitate that.  */
     mkdir_if_needed (CVSADM_BASE);
-    basefilename = xmalloc (10 + sizeof CVSADM_BASE + strlen (finfo->file));
-    strcpy (basefilename, CVSADM_BASE);
-    strcat (basefilename, "/");
-    strcat (basefilename, finfo->file);
+    (void) xasprintf (&basefilename, "%s/%s", CVSADM_BASE, finfo->file);
     copy_file (finfo->file, basefilename);
     free (basefilename);
 
@@ -444,10 +443,7 @@
     if (noexec)
        return 0;
 
-    basefilename = xmalloc (10 + sizeof CVSADM_BASE + strlen (finfo->file));
-    strcpy (basefilename, CVSADM_BASE);
-    strcat (basefilename, "/");
-    strcat (basefilename, finfo->file);
+    (void) xasprintf (&basefilename, "%s/%s", CVSADM_BASE, finfo->file);
     if (!isfile (basefilename))
     {
        /* This file apparently was never cvs edit'd (e.g. we are uneditting
@@ -598,16 +594,13 @@
 }
 
 void
-mark_up_to_date (char *file)
+mark_up_to_date (const char *file)
 {
     char *base;
 
     /* The file is up to date, so we better get rid of an out of
        date file in CVSADM_BASE.  */
-    base = xmalloc (strlen (file) + 80);
-    strcpy (base, CVSADM_BASE);
-    strcat (base, "/");
-    strcat (base, file);
+    (void) xasprintf (&base, "%s/%s", CVSADM_BASE, file);
     if (unlink_file (base) < 0 && ! existence_error (errno))
        error (0, errno, "cannot remove %s", file);
     free (base);
@@ -615,7 +608,7 @@
 
 
 void
-editor_set (char *filename, char *editor, char *val)
+editor_set (const char *filename, const char *editor, const char *val)
 {
     char *edlist;
     char *newlist;
@@ -636,26 +629,27 @@
 
 struct notify_proc_args {
     /* What kind of notification, "edit", "tedit", etc.  */
-    char *type;
+    const char *type;
     /* User who is running the command which causes notification.  */
-    char *who;
+    const char *who;
     /* User to be notified.  */
-    char *notifyee;
+    const char *notifyee;
     /* File.  */
-    char *file;
+    const char *file;
 };
 
-static int notify_proc ( char *repository, char *filter, void *closure );
+static int notify_proc (const char *repository, const char *filter,
+                       void *closure);
 
 static int
-notify_proc(char *repository, char *filter, void *closure)
+notify_proc(const char *repository, const char *filter, void *closure)
 {
     FILE *pipefp;
     char *prog;
     char *expanded_prog;
-    char *p;
+    const char *p;
     char *q;
-    char *srepos;
+    const char *srepos;
     struct notify_proc_args *args = (struct notify_proc_args *)closure;
 
     srepos = Short_Repository (repository);
@@ -716,7 +710,8 @@
    an error so that server.c can know whether to report Notified back
    to the client.  */
 void
-notify_do (int type, char *filename, char *who, char *val, char *watches, char 
*repository)
+notify_do (int type, const char *filename, const char *who, const char *val,
+    const char *watches, const char *repository)
 {
     static struct addremove_args blank;
     struct addremove_args args;
@@ -827,6 +822,7 @@
 
        if (notif != NULL)
        {
+           char *notifyee;
            struct notify_proc_args args;
            size_t len = endp - p;
            FILE *fp;
@@ -835,15 +831,8 @@
            size_t line_len = 0;
 
            args.notifyee = NULL;
-           usersname = xmalloc (strlen (current_parsed_root->directory)
-                                + sizeof CVSROOTADM
-                                + sizeof CVSROOTADM_USERS
-                                + 20);
-           strcpy (usersname, current_parsed_root->directory);
-           strcat (usersname, "/");
-           strcat (usersname, CVSROOTADM);
-           strcat (usersname, "/");
-           strcat (usersname, CVSROOTADM_USERS);
+           (void) xasprintf (&usersname, "%s/%s/%s",
+               current_parsed_root->directory, CVSROOTADM, CVSROOTADM_USERS);
            fp = CVS_FOPEN (usersname, "r");
            if (fp == NULL && !existence_error (errno))
                error (0, errno, "cannot read %s", usersname);
@@ -880,9 +869,9 @@
 
            if (args.notifyee == NULL)
            {
-               args.notifyee = xmalloc (endp - p + 1);
-               strncpy (args.notifyee, p, endp - p);
-               args.notifyee[endp - p] = '\0';
+               args.notifyee = notifyee = xmalloc (endp - p + 1);
+               strncpy (notifyee, p, endp - p);
+               notifyee[endp - p] = '\0';
            }
 
            args.type = notif;
@@ -891,7 +880,8 @@
 
            (void) Parse_Info (CVSROOTADM_NOTIFY, repository, notify_proc,
                        PIOPT_ALL, &args);
-           free (args.notifyee);
+           free (notifyee);
+           args.notifyee = NULL;
        }
 
        p = nextp;
@@ -929,7 +919,7 @@
 #ifdef CLIENT_SUPPORT
 /* Check and send notifications.  This is only for the client.  */
 void
-notify_check (char *repository, char *update_dir)
+notify_check (const char *repository, const char *update_dir)
 {
     FILE *fp;
     char *line = NULL;
Index: src/edit.h
===================================================================
RCS file: /cvs/ccvs/src/edit.h,v
retrieving revision 1.7
diff -u -u -r1.7 edit.h
--- src/edit.h  23 Jul 2003 20:42:25 -0000      1.7
+++ src/edit.h  25 Oct 2003 02:17:32 -0000
@@ -17,7 +17,7 @@
 /* Check to see if any notifications are sitting around in need of being
    sent.  These are the notifications stored in CVSADM_NOTIFY (edit,unedit);
    commit calls notify_do directly.  */
-extern void notify_check (char *repository, char *update_dir);
+extern void notify_check (const char *repository, const char *update_dir);
 #endif /* CLIENT_SUPPORT */
 
 /* Issue a notification for file FILENAME.  TYPE is 'E' for edit, 'U'
@@ -25,14 +25,16 @@
    For TYPE 'E', VAL is the time+host+directory data which goes in
    _editors, and WATCHES is zero or more of E,U,C, in that order, to specify
    what kinds of temporary watches to set.  */
-extern void notify_do (int type, char *filename, char *who,
-                             char *val, char *watches, char *repository);
+extern void notify_do (int type, const char *filename, const char *who,
+                      const char *val, const char *watches,
+                      const char *repository);
 
 /* Set attributes to reflect the fact that EDITOR is editing FILENAME.
    VAL is time+host+directory, or NULL if we are to say that EDITOR is
    *not* editing FILENAME.  */
-extern void editor_set (char *filename, char *editor, char *val);
+extern void editor_set (const char *filename, const char *editor,
+                       const char *val);
 
 /* Take note of the fact that FILE is up to date (this munges CVS/Base;
    processing of CVS/Entries is done separately).  */
-extern void mark_up_to_date (char *file);
+extern void mark_up_to_date (const char *file);
Index: src/entries.c
===================================================================
RCS file: /cvs/ccvs/src/entries.c,v
retrieving revision 1.53
diff -u -u -r1.53 entries.c
--- src/entries.c       30 Sep 2003 21:47:01 -0000      1.53
+++ src/entries.c       25 Oct 2003 02:17:32 -0000
@@ -154,7 +154,7 @@
  * Removes the argument file from the Entries file if necessary.
  */
 void
-Scratch_Entry (List *list, char *fname)
+Scratch_Entry (List *list, const char *fname)
 {
     Node *node;
 
@@ -191,7 +191,7 @@
  * removing the old entry first, if necessary.
  */
 void
-Register (List *list, char *fname, char *vn, char *ts, char *options, char 
*tag, char *date, char *ts_conflict)
+Register (List *list, const char *fname, const char *vn, const char *ts, const 
char *options, const char *tag, const char *date, const char *ts_conflict)
 {
     Entnode *entnode;
     Node *node;
@@ -423,7 +423,7 @@
    messages, or NULL if not known (that is, noone has gotten around
    to updating the caller to pass in the information).  */
 List *
-Entries_Open (int aflag, char *update_dir)
+Entries_Open (int aflag, const char *update_dir)
 {
     List *entries;
     struct stickydirtag *sdtp = NULL;
@@ -597,7 +597,7 @@
  * Write out the CVS/Template file.
  */
 void
-WriteTemplate (char *update_dir, int xdotemplate, char *repository)
+WriteTemplate (const char *update_dir, int xdotemplate, const char *repository)
 {
 #ifdef SERVER_SUPPORT
     TRACE (1, "Write_Template (%s, %s)", update_dir, repository);
@@ -623,7 +623,7 @@
  * Write out/Clear the CVS/Tag file.
  */
 void
-WriteTag (char *dir, char *tag, char *date, int nonbranch, char *update_dir, 
char *repository)
+WriteTag (const char *dir, const char *tag, const char *date, int nonbranch, 
const char *update_dir, const char *repository)
 {
     FILE *fout;
     char *tmp;
@@ -631,13 +631,10 @@
     if (noexec)
        return;
 
-    tmp = xmalloc ((dir ? strlen (dir) : 0)
-                  + sizeof (CVSADM_TAG)
-                  + 10);
     if (dir == NULL)
-       (void) strcpy (tmp, CVSADM_TAG);
+       tmp = xstrdup(CVSADM_TAG);
     else
-       (void) sprintf (tmp, "%s/%s", dir, CVSADM_TAG);
+       (void) xasprintf (&tmp, "%s/%s", dir, CVSADM_TAG);
 
     if (tag || date)
     {
@@ -822,14 +819,9 @@
     if (!noexec)
     {
        if (parent == NULL)
-           entfilename = CVSADM_ENTLOG;
+           entfilename = xstrdup (CVSADM_ENTLOG);
        else
-       {
-           entfilename = xmalloc (strlen (parent)
-                                  + sizeof CVSADM_ENTLOG
-                                  + 10);
-           sprintf (entfilename, "%s/%s", parent, CVSADM_ENTLOG);
-       }
+           (void) xasprintf (&entfilename, "%s/%s", parent, CVSADM_ENTLOG);
 
        entfile = CVS_FOPEN (entfilename, "a");
        if (entfile == NULL)
@@ -847,7 +839,8 @@
            }
            else
            {
-               sprintf (entfilename, "%s/%s", parent, CVSADM);
+               free (entfilename);
+               (void) xasprintf (&entfilename, "%s/%s", parent, CVSADM);
                if (! isdir (entfilename))
                {
                    free (entfilename);
@@ -868,11 +861,8 @@
        if (fclose (entfile) == EOF)
            error (1, errno, "error closing %s", entfilename);
 
-       if (parent != NULL)
-       {
-           free (entfilename);
-           entfilename = NULL;
-       }
+       free (entfilename);
+       entfilename = NULL;
     }
 
     return entnode;
@@ -987,23 +977,16 @@
        computation probably should be broken out into a separate function,
        as recurse.c does it too and places like Entries_Open should be
        doing it.  */
-    baserev_fullname = xmalloc (sizeof (CVSADM_BASEREV)
-                               + strlen (finfo->update_dir)
-                               + 2);
-    baserev_fullname[0] = '\0';
-    baserevtmp_fullname = xmalloc (sizeof (CVSADM_BASEREVTMP)
-                                  + strlen (finfo->update_dir)
-                                  + 2);
-    baserevtmp_fullname[0] = '\0';
     if (finfo->update_dir[0] != '\0')
     {
-       strcat (baserev_fullname, finfo->update_dir);
-       strcat (baserev_fullname, "/");
-       strcat (baserevtmp_fullname, finfo->update_dir);
-       strcat (baserevtmp_fullname, "/");
+       (void) xasprintf (&baserev_fullname, "%s/%s", finfo->update_dir,
+           CVSADM_BASEREV);
+       (void) xasprintf (&baserevtmp_fullname, "%s/%s",
+           finfo->update_dir, CVSADM_BASEREVTMP);
+    } else {
+       baserev_fullname = xstrdup(CVSADM_BASEREV);
+       baserevtmp_fullname = xstrdup(CVSADM_BASEREVTMP);
     }
-    strcat (baserev_fullname, CVSADM_BASEREV);
-    strcat (baserevtmp_fullname, CVSADM_BASEREVTMP);
 
     fp = CVS_FOPEN (CVSADM_BASEREV, "r");
     if (fp == NULL)
Index: src/error.c
===================================================================
RCS file: /cvs/ccvs/src/error.c,v
retrieving revision 1.39
diff -u -u -r1.39 error.c
--- src/error.c 5 Oct 2003 00:37:16 -0000       1.39
+++ src/error.c 25 Oct 2003 02:17:32 -0000
@@ -161,7 +161,7 @@
    Exit with status EXIT_FAILURE if STATUS is nonzero.  */
 /* VARARGS */
 void
-fperrmsg (FILE *fp, int status, int errnum, char *message, ...)
+fperrmsg (FILE *fp, int status, int errnum, const char *message, ...)
 {
     va_list args;
 
Index: src/exithandle.c
===================================================================
RCS file: /cvs/ccvs/src/exithandle.c,v
retrieving revision 1.1
diff -u -u -r1.1 exithandle.c
--- src/exithandle.c    5 Oct 2003 03:32:45 -0000       1.1
+++ src/exithandle.c    25 Oct 2003 02:17:32 -0000
@@ -44,6 +44,6 @@
 void
 cleanup_register (void (*handler) (void))
 {
-    signals_register (handler);
+    signals_register ((void (*)(int))handler);
     atexit (handler);
 }
Index: src/expand_path.c
===================================================================
RCS file: /cvs/ccvs/src/expand_path.c,v
retrieving revision 1.26
diff -u -u -r1.26 expand_path.c
--- src/expand_path.c   23 Jul 2003 20:42:25 -0000      1.26
+++ src/expand_path.c   25 Oct 2003 02:17:32 -0000
@@ -15,7 +15,7 @@
 #include "cvs.h"
 #include <sys/types.h>
 
-static char *expand_variable (char *env, char *file, int line);
+static char *expand_variable (const char *env, const char *file, int line);
 
 
 /* User variables.  */
@@ -34,9 +34,9 @@
    variables in a file in the $CVSROOT/CVSROOT directory too.  */
 
 void
-variable_set (char *nameval)
+variable_set (const char *nameval)
 {
-    char *p;
+    const char *p;
     char *name;
     Node *node;
 
@@ -87,9 +87,9 @@
    to something; LINE can be zero to indicate the line number is not
    known.  */
 char *
-expand_path (char *name, char *file, int line)
+expand_path (const char *name, const char *file, int line)
 {
-    char *s;
+    const char *s;
     char *d;
 
     char *mybuf = NULL;
@@ -175,7 +175,7 @@
     if (*s++ == '~')
     {
        char *t;
-       char *p=s;
+       char *p= (char *)s;
        if (*s=='/' || *s==0)
            t = get_homedir ();
        else
@@ -262,7 +262,7 @@
 }
 
 static char *
-expand_variable (char *name, char *file, int line)
+expand_variable (const char *name, const char *file, int line)
 {
     if (strcmp (name, CVSROOT_ENV) == 0)
        return current_parsed_root->original;
Index: src/fileattr.c
===================================================================
RCS file: /cvs/ccvs/src/fileattr.c,v
retrieving revision 1.24
diff -u -u -r1.24 fileattr.c
--- src/fileattr.c      19 Aug 2003 13:35:15 -0000      1.24
+++ src/fileattr.c      25 Oct 2003 02:17:33 -0000
@@ -41,7 +41,7 @@
 /* Note that if noone calls fileattr_get, this is very cheap.  No stat(),
    no open(), no nothing.  */
 void
-fileattr_startdir (char *repos)
+fileattr_startdir (const char *repos)
 {
     assert (fileattr_stored_repos == NULL);
     fileattr_stored_repos = xstrdup (repos);
@@ -76,14 +76,7 @@
        at attributes.  */
     assert (fileattr_stored_repos != NULL);
 
-    fname = xmalloc (strlen (fileattr_stored_repos)
-                    + 1
-                    + sizeof (CVSREP_FILEATTR)
-                    + 1);
-
-    strcpy (fname, fileattr_stored_repos);
-    strcat (fname, "/");
-    strcat (fname, CVSREP_FILEATTR);
+    (void) xasprintf (&fname, "%s/%s", fileattr_stored_repos, CVSREP_FILEATTR);
 
     attr_read_attempted = 1;
     fp = CVS_FOPEN (fname, FOPEN_BINARY_READ);
@@ -350,10 +343,7 @@
        node->type = FILEATTR;
        node->delproc = fileattr_delproc;
        node->key = xstrdup (filename);
-       node->data = xmalloc (strlen (attrname) + 1 + strlen (attrval) + 1);
-       strcpy (node->data, attrname);
-       strcat (node->data, "=");
-       strcat (node->data, attrval);
+       (void) xasprintf(&node->data, "%s=%s", attrname, attrval);
        addnode (attrlist, node);
     }
 
@@ -509,9 +499,7 @@
                     + sizeof (CVSREP_FILEATTR)
                     + 1);
 
-    strcpy (fname, fileattr_stored_repos);
-    strcat (fname, "/");
-    strcat (fname, CVSREP_FILEATTR);
+    (void) xasprintf(&fname, "%s/%s", fileattr_stored_repos, CVSREP_FILEATTR);
 
     if (list_isempty (attrlist)
        && fileattr_default_attrs == NULL
@@ -529,9 +517,8 @@
        /* Now remove CVSREP directory, if empty.  The main reason we bother
           is that CVS 1.6 and earlier will choke if a CVSREP directory
           exists, so provide the user a graceful way to remove it.  */
-       strcpy (fname, fileattr_stored_repos);
-       strcat (fname, "/");
-       strcat (fname, CVSREP);
+       free (fname);
+       (void) xasprintf(&fname, "%s/%s", fileattr_stored_repos, CVSREP);
        if (CVS_RMDIR (fname) < 0)
        {
            if (errno != ENOTEMPTY
@@ -556,13 +543,7 @@
            /* Maybe the CVSREP directory doesn't exist.  Try creating it.  */
            char *repname;
 
-           repname = xmalloc (strlen (fileattr_stored_repos)
-                              + 1
-                              + sizeof (CVSREP)
-                              + 1);
-           strcpy (repname, fileattr_stored_repos);
-           strcat (repname, "/");
-           strcat (repname, CVSREP);
+           (void) xasprintf (&repname, "%s/%s", fileattr_stored_repos, CVSREP);
 
            if (CVS_MKDIR (repname, 0777) < 0 && errno != EEXIST)
            {
Index: src/fileattr.h
===================================================================
RCS file: /cvs/ccvs/src/fileattr.h,v
retrieving revision 1.12
diff -u -u -r1.12 fileattr.h
--- src/fileattr.h      23 Jul 2003 20:42:25 -0000      1.12
+++ src/fileattr.h      25 Oct 2003 02:17:33 -0000
@@ -56,7 +56,7 @@
 /* Prepare for a new directory with repository REPOS.  If REPOS is NULL,
    then prepare for a "non-directory"; the caller can call fileattr_write
    and fileattr_free, but must not call fileattr_get or fileattr_set.  */
-extern void fileattr_startdir (char *repos);
+extern void fileattr_startdir (const char *repos);
 
 /* Get the attribute ATTRNAME for file FILENAME.  The return value
    points into memory managed by the fileattr_* routines, should not
Index: src/filesubr.c
===================================================================
RCS file: /cvs/ccvs/src/filesubr.c,v
retrieving revision 1.77
diff -u -u -r1.77 filesubr.c
--- src/filesubr.c      8 Sep 2003 14:59:00 -0000       1.77
+++ src/filesubr.c      25 Oct 2003 02:17:33 -0000
@@ -257,7 +257,6 @@
 open_file (const char *name, const char *mode)
 {
     FILE *fp;
-
     if ((fp = fopen (name, mode)) == NULL)
        error (1, errno, "cannot open %s", name);
     return (fp);
@@ -310,7 +309,7 @@
    other errors.  Returns 0 if directory was created; 1 if it already
    existed.  */
 int
-mkdir_if_needed (char *name)
+mkdir_if_needed (const char *name)
 {
     if (mkdir (name, 0777) < 0)
     {
@@ -330,7 +329,7 @@
  * have unexpected consequences for some uses of xchmod.
  */
 void
-xchmod (char *fname, int writable)
+xchmod (const char *fname, int writable)
 {
     struct stat sb;
     mode_t mode, oumask;
@@ -473,8 +472,7 @@
                            strcmp (dp->d_name, "..") == 0)
                    continue;
 
-               buf = xmalloc (strlen (path) + strlen (dp->d_name) + 5);
-               sprintf (buf, "%s/%s", path, dp->d_name);
+               (void) xasprintf (&buf, "%s/%s", path, dp->d_name);
 
                /* See comment in unlink_file_dir explanation of why we use
                   isdir instead of just calling unlink and checking the
@@ -707,8 +705,7 @@
 
     assert (filename != NULL);
 
-    fn = xmalloc (strlen (Tmpdir) + 11);
-    sprintf (fn, "%s/%s", Tmpdir, "cvsXXXXXX" );
+    (void) xasprintf (&fn, "%s/%s", Tmpdir, "cvsXXXXXX" );
     fd = mkstemp (fn);
 
     /* a NULL return will be interpreted by callers as an error and
@@ -846,14 +843,14 @@
 
 /* Return a pointer into PATH's last component.  */
 char *
-last_component (char *path)
+last_component (const char *path)
 {
     char *last = strrchr (path, '/');
     
     if (last && (last != path))
         return last + 1;
     else
-        return path;
+        return (char *)path;
 }
 
 /* Return the home directory.  Returns a pointer to storage
@@ -917,8 +914,8 @@
 char *
 strcat_filename_onto_homedir (const char *dir, const char *file)
 {
-    char *path = xmalloc (strlen (dir) + 1 + strlen(file) + 1);
-    sprintf (path, "%s/%s", dir, file);
+    char *path;
+    (void) xasprintf (&path, "%s/%s", dir, file);
     return path;
 }
 
Index: src/find_names.c
===================================================================
RCS file: /cvs/ccvs/src/find_names.c,v
retrieving revision 1.34
diff -u -u -r1.34 find_names.c
--- src/find_names.c    23 Jul 2003 20:42:25 -0000      1.34
+++ src/find_names.c    25 Oct 2003 02:17:33 -0000
@@ -18,9 +18,9 @@
 
 #include "cvs.h"
 
-static int find_dirs (char *dir, List * list, int checkadm,
+static int find_dirs (const char *dir, List * list, int checkadm,
                            List *entries);
-static int find_rcs (char *dir, List * list);
+static int find_rcs (const char *dir, List * list);
 static int add_subdir_proc (Node *, void *);
 static int register_subdir_proc (Node *, void *);
 
@@ -53,7 +53,7 @@
    list).  */
 
 List *
-Find_Names (char *repository, int which, int aflag, List **optentries)
+Find_Names (const char *repository, int which, int aflag, List **optentries)
 {
     List *entries;
     List *files;
@@ -92,8 +92,7 @@
        if (which & W_ATTIC)
        {
            char *dir;
-           dir = xmalloc (strlen (repository) + sizeof (CVSATTIC) + 10);
-           (void) sprintf (dir, "%s/%s", repository, CVSATTIC);
+           (void) xasprintf (&dir, "%s/%s", repository, CVSATTIC);
            if (find_rcs (dir, files) != 0
                && !existence_error (errno))
                /* For now keep this a fatal error, seems less useful
@@ -153,7 +152,7 @@
  * create a list of directories to traverse from the current directory
  */
 List *
-Find_Directories (char *repository, int which, List *entries)
+Find_Directories (const char *repository, int which, List *entries)
 {
     List *dirlist;
 
@@ -241,7 +240,7 @@
  * containing the files which were found before the error occurred).
  */
 static int
-find_rcs (char *dir, List *list)
+find_rcs (const char *dir, List *list)
 {
     Node *p;
     struct dirent *dp;
@@ -288,7 +287,7 @@
  * error, in which case errno is set to indicate the error.
  */
 static int
-find_dirs (char *dir, List *list, int checkadm, List *entries)
+find_dirs (const char *dir, List *list, int checkadm, List *entries)
 {
     Node *p;
     char *tmp = NULL;
Index: src/hardlink.c
===================================================================
RCS file: /cvs/ccvs/src/hardlink.c,v
retrieving revision 1.10
diff -u -u -r1.10 hardlink.c
--- src/hardlink.c      23 Jul 2003 20:42:25 -0000      1.10
+++ src/hardlink.c      25 Oct 2003 02:17:33 -0000
@@ -126,8 +126,7 @@
        /* file is a relative pathname; assume it's from the current
           working directory. */
        char *dir = xgetwd();
-       path = xmalloc (strlen(dir) + strlen(file) + 2);
-       sprintf (path, "%s/%s", dir, file);
+       (void) xasprintf (&path, "%s/%s", dir, file);
        free (dir);
     }
 
@@ -173,8 +172,7 @@
     else
     {
        char *dir = xgetwd();
-       path = (char *) xmalloc (strlen(dir) + strlen(file) + 2);
-       sprintf (path, "%s/%s", dir, file);
+       (void) xasprintf (&path, "%s/%s", dir, file);
        free (dir);
     }
 
@@ -189,8 +187,7 @@
     /* inodestr contains the hexadecimal representation of an
        inode, so it requires two bytes of text to represent
        each byte of the inode number. */
-    inodestr = (char *) xmalloc (2*sizeof(ino_t) + 1);
-    sprintf (inodestr, "%lx", (unsigned long) sb.st_ino);
+    (void) xasprintf (&inodestr, "%lx", (unsigned long) sb.st_ino);
 
     /* Make sure the files linked to this inode are sorted. */
     n = findnode (hardlist, inodestr);
@@ -271,9 +268,7 @@
 
     /* Look at this file in the hardlist and see whether the checked_out
        field is 1, meaning that it has been checked out during this CVS run. */
-    path = (char *)
-       xmalloc (strlen (dir) + strlen (node->key) + 2);
-    sprintf (path, "%s/%s", dir, node->key);
+    (void) xasprintf (&path, "%s/%s", dir, node->key);
     link = lookup_file_by_inode (path);
     free (path);
     free (dir);
Index: src/history.c
===================================================================
RCS file: /cvs/ccvs/src/history.c,v
retrieving revision 1.70
diff -u -u -r1.70 history.c
--- src/history.c       8 Oct 2003 22:31:46 -0000       1.70
+++ src/history.c       25 Oct 2003 02:17:34 -0000
@@ -500,9 +500,9 @@
                     * Use the epoch + 23 hours, so timezones east of GMT work.
                     */
                    static char f[] = "1/1/1970 23:00 %s";
-                   char *buf = xmalloc (sizeof (f) - 2 + strlen (optarg));
+                   char *buf;
                    time_t t;
-                   sprintf (buf, f, optarg);
+                   (void) xasprintf (&buf, f, optarg);
                    t = get_date (buf, (struct timeb *) NULL);
                    free (buf);
                    if (t == (time_t) -1)
@@ -670,9 +670,7 @@
        fname = xstrdup (histfile);
     else
     {
-       fname = xmalloc (strlen (current_parsed_root->directory) + sizeof 
(CVSROOTADM)
-                        + sizeof (CVSROOTADM_HISTORY) + 10);
-       (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory,
+       (void) xasprintf (&fname, "%s/%s/%s", current_parsed_root->directory,
                        CVSROOTADM, CVSROOTADM_HISTORY);
     }
 
@@ -695,14 +693,16 @@
 }
 
 void
-history_write (int type, char *update_dir, char *revs, char *name, char 
*repository)
+history_write (int type, const char *update_dir, const char *revs,
+    const char *name, const char *repository)
 {
     char *fname;
     char *workdir;
     char *username = getcaller ();
     int fd;
     char *line;
-    char *slash = "", *cp, *cp2, *repos;
+    char *slash = "", *cp;
+    const char *repos, *cp2;
     int i;
     static char *tilde = "";
     static char *PrCurDir = NULL;
@@ -713,9 +713,7 @@
        return;
     if ( strchr(logHistory, type) == NULL )    
        return;
-    fname = xmalloc (strlen (current_parsed_root->directory) + sizeof 
(CVSROOTADM)
-                    + sizeof (CVSROOTADM_HISTORY) + 3);
-    (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory,
+    (void) xasprintf (&fname, "%s/%s/%s", current_parsed_root->directory,
                    CVSROOTADM, CVSROOTADM_HISTORY);
 
     /* turn off history logging if the history file does not exist */
@@ -805,9 +803,7 @@
     else
        update_dir = "";
 
-    workdir = xmalloc (strlen (tilde) + strlen (PrCurDir) + strlen (slash)
-                      + strlen (update_dir) + 10);
-    (void) sprintf (workdir, "%s%s%s%s", tilde, PrCurDir, slash, update_dir);
+    (void) xasprintf (&workdir, "%s%s%s%s", tilde, PrCurDir, slash, 
update_dir);
 
     /*
      * "workdir" is the directory where the file "name" is. ("^~" == $HOME)
@@ -865,9 +861,7 @@
 
     if (!revs)
        revs = "";
-    line = xmalloc (strlen (username) + strlen (workdir) + strlen (repos)
-                   + strlen (revs) + strlen (name) + 100);
-    sprintf (line, "%c%08lx|%s|%s|%s|%s|%s\n",
+    (void) xasprintf (&line, "%c%08lx|%s|%s|%s|%s|%s\n",
             type, (long) time ((time_t *) NULL),
             username, workdir, repos, revs, name);
 
@@ -916,7 +910,6 @@
 static void
 save_file (char *dir, char *name, char *module)
 {
-    char *cp;
     struct file_list_str *fl;
 
     if (file_count == file_max)
@@ -926,28 +919,20 @@
                                                   file_max * sizeof (*fl));
     }
     fl = &file_list[file_count++];
-    fl->l_file = cp = xmalloc (strlen (dir) + strlen (name) + 2);
     fl->l_module = module;
 
     if (dir && *dir)
     {
        if (name && *name)
-       {
-           (void) strcpy (cp, dir);
-           (void) strcat (cp, "/");
-           (void) strcat (cp, name);
-       }
+           (void) xasprintf (&fl->l_file, "%s/%s", dir, name);
        else
-       {
-           *cp++ = '*';
-           (void) strcpy (cp, dir);
-       }
+           (void) xasprintf (&fl->l_file, "*%s", dir);
     }
     else
     {
        if (name && *name)
        {
-           (void) strcpy (cp, name);
+           fl->l_file = xstrdup (name);
        }
        else
        {
@@ -1341,10 +1326,7 @@
                {
                    if (strchr (cp, '/'))
                    {
-                       cmpfile = xmalloc (strlen (hr->repos)
-                                          + strlen (hr->file)
-                                          + 10);
-                       (void) sprintf (cmpfile, "%s/%s",
+                       (void) xasprintf (&cmpfile, "%s/%s",
                                        hr->repos, hr->file);
                        cp2 = cmpfile;
                    }
@@ -1480,8 +1462,7 @@
                  tm->tm_year+1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour,
                  tm->tm_min, tz_name, user_len, lr->user);
 
-       workdir = xmalloc (strlen (lr->dir) + strlen (lr->end) + 10);
-       (void) sprintf (workdir, "%s%s", lr->dir, lr->end);
+       (void) xasprintf (&workdir, "%s%s", lr->dir, lr->end);
        if ((cp = strrchr (workdir, '/')) != NULL)
        {
            if (lr->mod && !strcmp (++cp, lr->mod))
Index: src/ignore.c
===================================================================
RCS file: /cvs/ccvs/src/ignore.c,v
retrieving revision 1.43
diff -u -u -r1.43 ignore.c
--- src/ignore.c        23 Jul 2003 20:42:26 -0000      1.43
+++ src/ignore.c        25 Oct 2003 02:17:34 -0000
@@ -74,7 +74,7 @@
        char *file = xmalloc (strlen (current_parsed_root->directory) + sizeof 
(CVSROOTADM)
                              + sizeof (CVSROOTADM_IGNORE) + 10);
        /* Then add entries found in repository, if it exists */
-       (void) sprintf (file, "%s/%s/%s", current_parsed_root->directory,
+       (void) xasprintf (&file, "%s/%s/%s", current_parsed_root->directory,
                        CVSROOTADM, CVSROOTADM_IGNORE);
        ign_add_file (file, 0);
        free (file);
@@ -106,7 +106,7 @@
  * argument is set.
  */
 void
-ign_add_file (char *file, int hold)
+ign_add_file (const char *file, int hold)
 {
     FILE *fp;
     char *line = NULL;
@@ -165,7 +165,7 @@
 
 /* Parse a line of space-separated wildcards and add them to the list. */
 void
-ign_add (char *ign, int hold)
+ign_add (const char *ign, int hold)
 {
     if (!ign || !*ign)
        return;
@@ -234,7 +234,8 @@
        }
 
        /* find the end of this token */
-       for (mark = ign; *mark && !isspace ((unsigned char) *mark); mark++)
+       for (mark = (char *)ign; *mark && !isspace ((unsigned char) *mark);
+           mark++)
             /* do nothing */ ;
 
        save = *mark;
@@ -258,7 +259,7 @@
 
 /* Return 1 if the given filename should be ignored by update or import. */
 int
-ign_name (char *name)
+ign_name (const char *name)
 {
     char **cpp = ign_list;
 
@@ -315,7 +316,7 @@
 
 /* Add a directory to list of dirs to ignore.  */
 void
-ign_dir_add (char *name)
+ign_dir_add (const char *name)
 {
     /* Make sure we've got the space for the entry.  */
     if (dir_ign_current <= dir_ign_max)
@@ -333,7 +334,7 @@
 /* Return nonzero if NAME is part of the list of directories to ignore.  */
 
 int
-ignore_directory (char *name)
+ignore_directory (const char *name)
 {
     int i;
 
@@ -359,14 +360,15 @@
  * directory with a CVS administration directory is known.
  */
 void
-ignore_files (List *ilist, List *entries, char *update_dir, Ignore_proc proc)
+ignore_files (List *ilist, List *entries, const char *update_dir,
+    Ignore_proc proc)
 {
     int subdirs;
     DIR *dirp;
     struct dirent *dp;
     struct stat sb;
     char *file;
-    char *xdir;
+    const char *xdir;
     List *files;
     Node *p;
 
@@ -422,8 +424,7 @@
                   this directory if there is a CVS subdirectory.
                   This will normally be the case, but the user may
                   have messed up the working directory somehow.  */
-               p = xmalloc (strlen (file) + sizeof CVSADM + 10);
-               sprintf (p, "%s/%s", file, CVSADM);
+               (void) xasprintf (&p, "%s/%s", file, CVSADM);
                dir = isdir (p);
                free (p);
                if (dir)
@@ -456,8 +457,7 @@
                {
                    char *temp;
 
-                   temp = xmalloc (strlen (file) + sizeof (CVSADM) + 10);
-                   (void) sprintf (temp, "%s/%s", file, CVSADM);
+                   (void) xasprintf (&temp, "%s/%s", file, CVSADM);
                    if (isdir (temp))
                    {
                        free (temp);
Index: src/import.c
===================================================================
RCS file: /cvs/ccvs/src/import.c,v
retrieving revision 1.140
diff -u -u -r1.140 import.c
--- src/import.c        5 Oct 2003 00:37:16 -0000       1.140
+++ src/import.c        25 Oct 2003 02:17:34 -0000
@@ -19,7 +19,7 @@
 #include "cvs.h"
 #include "savecwd.h"
 
-static char *get_comment (char *user);
+static char *get_comment (const char *user);
 static int add_rev (char *message, RCSNode *rcs, char *vfile,
                          char *vers);
 static int add_tags (RCSNode *rcs, char *vfile, char *vtag, int targc,
@@ -174,10 +174,8 @@
            error (1, 0, "Set it or specify the '-d' option to %s.",
                   program_name);
        }
-       repository = xmalloc (strlen (current_parsed_root->directory)
-                             + strlen (argv[0])
-                             + 2);
-       (void) sprintf (repository, "%s/%s", current_parsed_root->directory, 
argv[0]);
+       (void) xasprintf (&repository, "%s/%s", current_parsed_root->directory,
+           argv[0]);
        repos_len = strlen (current_parsed_root->directory);
     }
     else
@@ -228,17 +226,10 @@
     }
     do_verify (&message, repository);
     msglen = message == NULL ? 0 : strlen (message);
-    if (msglen == 0 || message[msglen - 1] != '\n')
+    if (message == NULL || message[msglen - 1] != '\n')
     {
-       char *nm = xmalloc (msglen + 2);
-       *nm = '\0';
-       if (message != NULL)
-       {
-           (void) strcpy (nm, message);
-           free (message);
-       }
-       (void) strcat (nm + msglen, "\n");
-       message = nm;
+       char *nm = message ? message : "";
+       (void) xasprintf (&message, "%s\n", nm);
     }
 
 #ifdef CLIENT_SUPPORT
@@ -520,16 +511,12 @@
     char *rcs;
     int inattic = 0;
 
-    rcs = xmalloc (strlen (repository) + strlen (vfile) + sizeof (RCSEXT)
-                  + 5);
-    (void) sprintf (rcs, "%s/%s%s", repository, vfile, RCSEXT);
+    (void) xasprintf (&rcs, "%s/%s%s", repository, vfile, RCSEXT);
     if (!isfile (rcs))
     {
        char *attic_name;
 
-       attic_name = xmalloc (strlen (repository) + strlen (vfile) +
-                             sizeof (CVSATTIC) + sizeof (RCSEXT) + 10);
-       (void) sprintf (attic_name, "%s/%s/%s%s", repository, CVSATTIC,
+       (void) xasprintf (&attic_name, "%s/%s/%s%s", repository, CVSATTIC,
                        vfile, RCSEXT);
        if (!isfile (attic_name))
        {
@@ -905,7 +892,7 @@
 };
 
 static char *
-get_comment (char *user)
+get_comment (const char *user)
 {
     char *cp, *suffix;
     char *suffix_path;
@@ -957,7 +944,10 @@
    Return value is 0 for success, or nonzero for failure (in which
    case an error message will have already been printed).  */
 int
-add_rcs_file (char *message, char *rcs, char *user, char *add_vhead, char 
*key_opt, char *add_vbranch, char *vtag, int targc, char **targv, char 
*desctext, size_t desclen, FILE *add_logfp)
+add_rcs_file (const char *message, const char *rcs, const char *user,
+    const char *add_vhead, const char *key_opt, const char *add_vbranch,
+    const char *vtag, int targc, char **targv, const char *desctext,
+    size_t desclen, FILE *add_logfp)
     /* Log message for the addition.  Not used if add_vhead == NULL.  */
                   
     /* Filename of the RCS file to create.  */
@@ -1002,8 +992,8 @@
     int i, ierrno, err = 0;
     mode_t mode;
     char *tocvsPath;
-    char *userfile;
-    char *local_opt = key_opt;
+    const char *userfile;
+    const char *local_opt = key_opt;
     char *free_opt = NULL;
     mode_t file_type;
 
@@ -1433,9 +1423,9 @@
  * to indicate the error.  If not, return a nonnegative value.
  */
 int
-expand_at_signs (char *buf, off_t size, FILE *fp)
+expand_at_signs (const char *buf, off_t size, FILE *fp)
 {
-    register char *cp, *next;
+    register const char *cp, *next;
 
     cp = buf;
     while ((next = memchr (cp, '@', size)) != NULL)
@@ -1507,6 +1497,7 @@
     char *cp;
     int ierrno, err;
     char *rcs = NULL;
+    char *new;
 
     if (islink (dir))
        return (0);
@@ -1518,20 +1509,12 @@
 
     /* Concatenate DIR to the end of REPOSITORY.  */
     if (repository[0] == '\0')
-    {
-       char *new = xstrdup (dir);
-       free (repository);
-       repository = new;
-    }
+       new = xstrdup (dir);
     else
-    {
-       char *new = xmalloc (strlen (repository) + strlen (dir) + 10);
-       strcpy (new, repository);
-       (void) strcat (new, "/");
-       (void) strcat (new, dir);
-       free (repository);
-       repository = new;
-    }
+       (void) xasprintf (&new, "%s/%s", repository, dir);
+
+    free (repository);
+    repository = new;
 
 #ifdef CLIENT_SUPPORT
     if (!quiet && !current_parsed_root->isremote)
@@ -1554,8 +1537,7 @@
     if (!isdir (repository))
 #endif
     {
-       rcs = xmalloc (strlen (repository) + sizeof (RCSEXT) + 5);
-       (void) sprintf (rcs, "%s%s", repository, RCSEXT);
+       (void) xasprintf (&rcs, "%s%s", repository, RCSEXT);
        if (isfile (repository) || isfile(rcs))
        {
            fperrmsg (logfp, 0, 0,
Index: src/lock.c
===================================================================
RCS file: /cvs/ccvs/src/lock.c,v
retrieving revision 1.83
diff -u -u -r1.83 lock.c
--- src/lock.c  14 Oct 2003 17:08:42 -0000      1.83
+++ src/lock.c  25 Oct 2003 02:17:34 -0000
@@ -87,7 +87,7 @@
        struct lock; it is allocated by the Reader_Lock caller or in the
        case of writelocks, it is just a pointer to the storage allocated
        for the ->key field.  */
-    char *repository;
+    const char *repository;
     /* Do we have a lock named CVSLCK?  */
     int have_lckdir;
     /* Note there is no way of knowing whether the readlock and writelock
@@ -96,7 +96,7 @@
 };
 
 static void remove_locks (void);
-static int readers_exist (char *repository);
+static int readers_exist (const char *repository);
 static int set_lock (struct lock *lock, int will_wait);
 static void clear_lock (struct lock *lock);
 static void set_lockers_name (struct stat *statp);
@@ -104,8 +104,8 @@
 static int unlock_proc (Node * p, void *closure);
 static int write_lock (struct lock *lock);
 static void lock_simple_remove (struct lock *lock);
-static void lock_wait (char *repository);
-static void lock_obtained (char *repository);
+static void lock_wait (const char *repository);
+static void lock_obtained (const char *repository);
 
 /* Malloc'd array containing the username of the whoever has the lock.
    Will always be non-NULL in the cases where it is needed.  */
@@ -150,12 +150,12 @@
    that only if the actual operation fails.  But for now we'll keep
    things simple).  */
 static char *
-lock_name (char *repository, char *name)
+lock_name (const char *repository, const char *name)
 {
     char *retval;
-    char *p;
+    const char *p;
     char *q;
-    char *short_repos;
+    const char *short_repos;
     mode_t save_umask = 0000;
     int saved_umask = 0;
 
@@ -165,8 +165,7 @@
     {
        /* This is the easy case.  Because the lock files go directly
           in the repository, no need to create directories or anything.  */
-       retval = xmalloc (strlen (repository) + strlen (name) + 10);
-       (void) sprintf (retval, "%s/%s", repository, name);
+       (void) xasprintf (&retval, "%s/%s", repository, name);
     }
     else
     {
@@ -453,7 +452,7 @@
  * Create a lock file for readers
  */
 int
-Reader_Lock (char *xrepository)
+Reader_Lock (const char *xrepository)
 {
     int err = 0;
     FILE *fp;
@@ -473,8 +472,7 @@
 
     if (readlock == NULL)
     {
-       readlock = xmalloc (strlen (hostname) + sizeof (CVSRFL) + 40);
-       (void) sprintf (readlock, 
+       (void) xasprintf (&readlock, 
 #ifdef HAVE_LONG_FILE_NAMES
                        "%s.%s.%ld", CVSRFL, hostname,
 #else
@@ -627,8 +625,7 @@
 
     if (writelock == NULL)
     {
-       writelock = xmalloc (strlen (hostname) + sizeof (CVSWFL) + 40);
-       (void) sprintf (writelock,
+       (void) xasprintf (&writelock,
 #ifdef HAVE_LONG_FILE_NAMES
                        "%s.%s.%ld", CVSWFL, hostname,
 #else
@@ -688,7 +685,7 @@
  * sleep a while and try again.
  */
 static int
-readers_exist (char *repository)
+readers_exist (const char *repository)
 {
     char *lockdir;
     char *line;
@@ -714,8 +711,7 @@
        {
            if (CVS_FNMATCH (CVSRFLPAT, dp->d_name, 0) == 0)
            {
-               line = xmalloc (strlen (lockdir) + 1 + strlen (dp->d_name) + 1);
-               (void) sprintf (line, "%s/%s", lockdir, dp->d_name);
+               (void) xasprintf (&line, "%s/%s", lockdir, dp->d_name);
                if ( CVS_STAT (line, &sb) != -1)
                {
 #ifdef CVS_FUDGELOCKS
@@ -775,8 +771,8 @@
     }
     else
     {
-       lockers_name = xmalloc (20);
-       (void) sprintf (lockers_name, "uid%lu", (unsigned long) statp->st_uid);
+       (void) xasprintf (&lockers_name, "uid%lu",
+           (unsigned long) statp->st_uid);
     }
 }
 
@@ -923,7 +919,7 @@
  * Print out a message that the lock is still held, then sleep a while.
  */
 static void
-lock_wait (char *repos)
+lock_wait (const char *repos)
 {
     time_t now;
     char *msg;
@@ -931,8 +927,7 @@
 
     (void) time (&now);
     tm_p = gmtime (&now);
-    msg = xmalloc (100 + strlen (lockers_name) + strlen (repos));
-    sprintf (msg, "[%8.8s] waiting for %s's lock in %s",
+    (void) xasprintf (&msg, "[%8.8s] waiting for %s's lock in %s",
             (tm_p ? asctime (tm_p) : ctime (&now)) + 11,
             lockers_name, repos);
     error (0, 0, "%s", msg);
@@ -947,7 +942,7 @@
  * Print out a message when we obtain a lock.
  */
 static void
-lock_obtained (char *repos)
+lock_obtained (const char *repos)
 {
     time_t now;
     char *msg;
@@ -955,8 +950,7 @@
 
     (void) time (&now);
     tm_p = gmtime (&now);
-    msg = xmalloc (100 + strlen (repos));
-    sprintf (msg, "[%8.8s] obtained lock in %s",
+    (void) xasprintf (&msg, "[%8.8s] obtained lock in %s",
             (tm_p ? asctime (tm_p) : ctime (&now)) + 11, repos);
     error (0, 0, "%s", msg);
     /* Call cvs_flusherr to ensure that the user sees this message as
@@ -966,16 +960,16 @@
 }
 
 static int lock_filesdoneproc (void *callerdat, int err,
-                                     char *repository, char *update_dir,
-                                     List *entries);
+                              const char *repository, const char *update_dir,
+                              List *entries);
 
 /*
  * Create a list of repositories to lock
  */
 /* ARGSUSED */
 static int
-lock_filesdoneproc (void *callerdat, int err, char *repository,
-                    char *update_dir, List *entries)
+lock_filesdoneproc (void *callerdat, int err, const char *repository,
+                    const char *update_dir, List *entries)
 {
     Node *p;
 
@@ -1005,7 +999,7 @@
        ( (FILEPROC) NULL, lock_filesdoneproc,
          (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL, argc,
          argv, local, which, aflag, CVS_LOCK_NONE,
-         (char *) NULL, 0, (char *) NULL );
+         (const char *) NULL, 0, (const char *) NULL );
     sortlist (lock_tree_list, fsortcmp);
     if (Writer_Lock (lock_tree_list) != 0)
        error (1, 0, "lock failed - giving up");
@@ -1015,7 +1009,7 @@
    a lock has been set with lock_dir_for_write; the new lock will replace
    the old one.  If REPOSITORY is NULL, don't do anything.  */
 void
-lock_dir_for_write (char *repository)
+lock_dir_for_write (const char *repository)
 {
     if (repository != NULL
        && (locked_dir == NULL
Index: src/log.c
===================================================================
RCS file: /cvs/ccvs/src/log.c,v
retrieving revision 1.88
diff -u -u -r1.88 log.c
--- src/log.c   23 Jul 2003 20:42:26 -0000      1.88
+++ src/log.c   25 Oct 2003 02:17:35 -0000
@@ -112,11 +112,11 @@
     RCSNode *rcs;
 };
 
-static int rlog_proc (int argc, char **argv, char *xwhere,
-                           char *mwhere, char *mfile, int shorten,
-                           int local_specified, char *mname, char *msg);
-static Dtype log_dirproc (void *callerdat, char *dir,
-                                char *repository, char *update_dir,
+static int rlog_proc (int argc, char **argv, const char *xwhere,
+                     const char *mwhere, const char *mfile, int shorten,
+                     int local_specified, const char *mname, const char *msg);
+static Dtype log_dirproc (void *callerdat, const char *dir,
+                                const char *repository, const char *update_dir,
                                 List *entries);
 static int log_fileproc (void *callerdat, struct file_info *finfo);
 static struct option_revlist *log_parse_revlist (const char *);
@@ -410,7 +410,8 @@
        for (i = 0; i < argc; i++)
        {
            err += do_module (db, argv[i], MISC, "Logging", rlog_proc,
-                            (char *) NULL, 0, local, 0, 0, (char *) NULL);
+                            (const char *) NULL, 0, local, 0, 0,
+                            (const char *) NULL);
        }
        close_module (db);
     }
@@ -459,10 +460,10 @@
 
 
 static int
-rlog_proc (int argc, char **argv, char *xwhere, char *mwhere, char *mfile, int 
shorten, int local, char *mname, char *msg)
+rlog_proc (int argc, char **argv, const char *xwhere, const char *mwhere,
+    const char *mfile, int shorten, int local, const char *mname,
+    const char *msg)
 {
-    /* Begin section which is identical to patch_proc--should this
-       be abstracted out somehow?  */
     char *myargv[2];
     int err = 0;
     int which;
@@ -471,60 +472,9 @@
 
     if (is_rlog)
     {
-       repository = xmalloc (strlen (current_parsed_root->directory) + strlen 
(argv[0])
-                             + (mfile == NULL ? 0 : strlen (mfile) + 1) + 2);
-       (void) sprintf (repository, "%s/%s", current_parsed_root->directory, 
argv[0]);
-       where = xmalloc (strlen (argv[0]) + (mfile == NULL ? 0 : strlen (mfile) 
+ 1)
-                        + 1);
-       (void) strcpy (where, argv[0]);
-
-       /* if mfile isn't null, we need to set up to do only part of the module 
*/
-       if (mfile != NULL)
-       {
-           char *cp;
-           char *path;
-
-           /* if the portion of the module is a path, put the dir part on 
repos */
-           if ((cp = strrchr (mfile, '/')) != NULL)
-           {
-               *cp = '\0';
-               (void) strcat (repository, "/");
-               (void) strcat (repository, mfile);
-               (void) strcat (where, "/");
-               (void) strcat (where, mfile);
-               mfile = cp + 1;
-           }
-
-           /* take care of the rest */
-           path = xmalloc (strlen (repository) + strlen (mfile) + 5);
-           (void) sprintf (path, "%s/%s", repository, mfile);
-           if (isdir (path))
-           {
-               /* directory means repository gets the dir tacked on */
-               (void) strcpy (repository, path);
-               (void) strcat (where, "/");
-               (void) strcat (where, mfile);
-           }
-           else
-           {
-               myargv[0] = argv[0];
-               myargv[1] = mfile;
-               argc = 2;
-               argv = myargv;
-           }
-           free (path);
-       }
-
-       /* cd to the starting repository */
-       if ( CVS_CHDIR (repository) < 0)
-       {
-           error (0, errno, "cannot chdir to %s", repository);
-           free (repository);
-           free( where );
-           return (1);
-       }
-       /* End section which is identical to patch_proc.  */
-
+       if (get_repository(&repository, &where, mfile, &argc, &argv, myargv)
+           == 0)
+           return -1;
        which = W_REPOS | W_ATTIC;
     }
     else
@@ -1152,9 +1102,8 @@
                {
                    if (nr->fields <= dots2 && (nr->fields & 1))
                    {
-                       char *p = xmalloc (strlen (nr->first) + 3);
-                       strcpy (p, nr->first);
-                       strcat (p, ".0");
+                       char *p;
+                       (void) xasprintf (&p, "%s.0", nr->first);
                        free (nr->first);
                        nr->first = p;
                        ++nr->fields;
@@ -1627,7 +1576,8 @@
  */
 /* ARGSUSED */
 static Dtype
-log_dirproc (void *callerdat, char *dir, char *repository, char *update_dir, 
List *entries)
+log_dirproc (void *callerdat, const char *dir, const char *repository,
+    const char *update_dir, List *entries)
 {
     if (!isdir (dir))
        return (R_SKIP_ALL);
Index: src/logmsg.c
===================================================================
RCS file: /cvs/ccvs/src/logmsg.c,v
retrieving revision 1.74
diff -u -u -r1.74 logmsg.c
--- src/logmsg.c        29 Aug 2003 19:00:12 -0000      1.74
+++ src/logmsg.c        25 Oct 2003 02:17:35 -0000
@@ -12,15 +12,15 @@
 
 static int find_type (Node * p, void *closure);
 static int fmt_proc (Node * p, void *closure);
-static int logfile_write (char *repository, char *filter,
-                         char *message, FILE * logfp, List * changes);
-static int rcsinfo_proc ( char *repository, char *template,
+static int logfile_write (const char *repository, const char *filter,
+                         const char *message, FILE * logfp, List * changes);
+static int rcsinfo_proc (const char *repository, const char *template,
                                 void *closure );
 static int title_proc (Node * p, void *closure);
-static int update_logfile_proc ( char *repository, char *filter,
+static int update_logfile_proc (const char *repository, const char *filter,
                                        void *closure);
 static void setup_tmpfile (FILE * xfp, char *xprefix, List * changes);
-static int verifymsg_proc ( char *repository, char *script,
+static int verifymsg_proc (const char *repository, const char *script,
                                   void *closure );
 
 static FILE *fp;
@@ -177,7 +177,8 @@
  *              -e option to the CVS executable.
  */
 void
-do_editor (char *dir, char **messagep, char *repository, List *changes)
+do_editor (const char *dir, char **messagep, const char *repository,
+    List *changes)
 {
     static int reuse_log_message = 0;
     char *line;
@@ -387,7 +388,7 @@
    independant of the running of an editor for getting a message.
  */
 void
-do_verify (char **messagep, char *repository)
+do_verify (char **messagep, const char *repository)
 {
     FILE *fp;
     char *fname;
@@ -535,7 +536,7 @@
  */
 /* ARGSUSED */
 static int
-rcsinfo_proc(char *repository, char *template, void *closure)
+rcsinfo_proc(const char *repository, const char *template, void *closure)
 {
     static char *last_template;
     FILE *tfp;
@@ -577,12 +578,13 @@
  */
 struct ulp_data {
     FILE *logfp;
-    char *message;
+    const char *message;
     List *changes;
 };
 
 void
-Update_Logfile (char *repository, char *xmessage, FILE *xlogfp, List *xchanges)
+Update_Logfile (const char *repository, const char *xmessage, FILE *xlogfp,
+    List *xchanges)
 {
     struct ulp_data ud;
 
@@ -604,7 +606,7 @@
  * callback proc to actually do the logfile write from Update_Logfile
  */
 static int
-update_logfile_proc(char *repository, char *filter, void *closure)
+update_logfile_proc(const char *repository, const char *filter, void *closure)
 {
     struct ulp_data *udp = (struct ulp_data *)closure;
     return (logfile_write (repository, filter, udp->message, udp->logfp,
@@ -699,7 +701,7 @@
  * filter program.
  */
 static int
-logfile_write (char *repository, char *filter, char *message, FILE *logfp, 
List *changes)
+logfile_write (const char *repository, const char *filter, const char 
*message, FILE *logfp, List *changes)
 {
     FILE *pipefp;
     char *prog;
@@ -764,7 +766,7 @@
     if (fmt_percent)
     {
        int len;
-       char *srepos;
+       const char *srepos;
        char *fmt_begin, *fmt_end;      /* beginning and end of the
                                           format string specified in
                                           filter. */
@@ -914,7 +916,7 @@
  *  message verification script.
  */
 static int
-verifymsg_proc(char *repository, char *script, void *closure)
+verifymsg_proc(const char *repository, const char *script, void *closure)
 {
     char **verifymsg_script = (char **)closure;
     if (*verifymsg_script && strcmp (*verifymsg_script, script) == 0)
Index: src/main.c
===================================================================
RCS file: /cvs/ccvs/src/main.c,v
retrieving revision 1.199
diff -u -u -r1.199 main.c
--- src/main.c  8 Oct 2003 15:50:54 -0000       1.199
+++ src/main.c  25 Oct 2003 02:17:35 -0000
@@ -322,7 +322,7 @@
 
 
 unsigned long int
-lookup_command_attribute (char *cmd_name)
+lookup_command_attribute (const char *cmd_name)
 {
     const struct cmd *cm;
 
@@ -790,16 +790,14 @@
        if (tmpdir_update_env)
        {
            char *env;
-           env = xmalloc (strlen (TMPDIR_ENV) + strlen (Tmpdir) + 1 + 1);
-           (void) sprintf (env, "%s=%s", TMPDIR_ENV, Tmpdir);
+           (void) xasprintf (&env, "%s=%s", TMPDIR_ENV, Tmpdir);
            (void) putenv (env);
            /* do not free env, as putenv has control of it */
        }
        {
            char *env;
            /* XXX pid < 10^32 */
-           env = xmalloc (strlen (CVS_PID_ENV) + 1 + 32 + 1);
-           (void) sprintf (env, "%s=%ld", CVS_PID_ENV, (long) getpid ());
+           (void) xasprintf (&env, "%s=%ld", CVS_PID_ENV, (long) getpid ());
            (void) putenv (env);
            /* do not free env, as putenv has control of it */
        }
@@ -951,10 +949,8 @@
                    char *path;
                    int save_errno;
 
-                   path = xmalloc (strlen (current_parsed_root->directory)
-                                   + sizeof (CVSROOTADM)
-                                   + 2);
-                   (void) sprintf (path, "%s/%s", 
current_parsed_root->directory, CVSROOTADM);
+                   (void) xasprintf (&path, "%s/%s", 
+                       current_parsed_root->directory, CVSROOTADM);
                    if (!isaccessible (path, R_OK | X_OK))
                    {
                        save_errno = errno;
@@ -974,9 +970,7 @@
                {
                    static char *prev;
                    char *env;
-                   env = xmalloc (strlen (CVSROOT_ENV) + strlen (CVSroot)
-                                  + 1 + 1);
-                   (void) sprintf (env, "%s=%s", CVSROOT_ENV, CVSroot);
+                   (void) xasprintf (&env, "%s=%s", CVSROOT_ENV, CVSroot);
                    (void) putenv (env);
                    /* do not free env yet, as putenv has control of it */
                    /* but do free the previous value, if any */
@@ -1080,7 +1074,7 @@
 }
 
 char *
-Make_Date (char *rawdate)
+Make_Date (const char *rawdate)
 {
     time_t unixtime;
 
Index: src/mkmodules.c
===================================================================
RCS file: /cvs/ccvs/src/mkmodules.c,v
retrieving revision 1.77
diff -u -u -r1.77 mkmodules.c
--- src/mkmodules.c     8 Oct 2003 22:31:46 -0000       1.77
+++ src/mkmodules.c     25 Oct 2003 02:17:35 -0000
@@ -362,7 +362,7 @@
 
 /* Rebuild the checked out administrative files in directory DIR.  */
 int
-mkmodules (char *dir)
+mkmodules (const char *dir)
 {
     struct saved_cwd cwd;
     char *temp;
@@ -549,15 +549,19 @@
     if (noexec)
        return 0;
 
-    rcs = xmalloc (strlen (file) + 5);
-    strcpy (rcs, file);
-    strcat (rcs, RCSEXT);
+    (void) xasprintf (&rcs, "%s%s", file, RCSEXT);
     if (!isfile (rcs))
     {
        free (rcs);
        return (1);
     }
     rcsnode = RCS_parsercsfile (rcs);
+    if (rcsnode == NULL)
+    {
+       error (0, 0, "failed to parse rcs file %s",
+              rcs);
+       goto done;
+    }
     retcode = RCS_checkout (rcsnode, NULL, NULL, NULL, NULL, temp,
                            (RCSCHECKOUTPROC) NULL, (void *) NULL);
     if (retcode != 0)
@@ -567,6 +571,7 @@
        error (0, 0, "failed to check out %s file",
               file);
     }
+done:
     freercsnode (&rcsnode);
     free (rcs);
     return (retcode);
@@ -778,8 +783,7 @@
     char *rcs;
 
     /* Set "x" bits if set in original. */
-    rcs = xmalloc (strlen (real) + sizeof (RCSEXT) + 10);
-    (void) sprintf (rcs, "%s%s", real, RCSEXT);
+    (void) xasprintf (&rcs, "%s%s", real, RCSEXT);
     statbuf.st_mode = 0; /* in case rcs file doesn't exist, but it should... */
     if (CVS_STAT (rcs, &statbuf) < 0
        && !existence_error (errno))
@@ -788,8 +792,7 @@
 
     if (chmod (temp, 0444 | (statbuf.st_mode & 0111)) < 0)
        error (0, errno, "warning: cannot chmod %s", temp);
-    bak = xmalloc (strlen (real) + sizeof (BAKPREFIX) + 10);
-    (void) sprintf (bak, "%s%s", BAKPREFIX, real);
+    (void) xasprintf (&bak, "%s%s", BAKPREFIX, real);
 
     /* rm .#loginfo */
     if (unlink_file (bak) < 0
@@ -822,8 +825,6 @@
     char *adm;
     /* Name of this administrative file.  */
     char *info;
-    /* Name of ,v file for this administrative file.  */
-    char *info_v;
     /* Exit status.  */
     int err;
 
@@ -851,8 +852,8 @@
        which needs to be created.  */
     mkdir_if_needed (current_parsed_root->directory);
 
-    adm = xmalloc (strlen (current_parsed_root->directory) + sizeof 
(CVSROOTADM) + 2);
-    sprintf (adm, "%s/%s", current_parsed_root->directory, CVSROOTADM);
+    (void) xasprintf (&adm, "%s/%s", current_parsed_root->directory,
+       CVSROOTADM);
     mkdir_if_needed (adm);
 
     /* This is needed because we pass "fileptr->filename" not "info"
@@ -867,24 +868,20 @@
 
     /* 80 is long enough for all the administrative file names, plus
        "/" and so on.  */
-    info = xmalloc (strlen (adm) + 80);
-    info_v = xmalloc (strlen (adm) + 80);
     for (fileptr = filelist; fileptr && fileptr->filename; ++fileptr)
     {
+       char *info_v;
        if (fileptr->contents == NULL)
            continue;
-       strcpy (info, adm);
-       strcat (info, "/");
-       strcat (info, fileptr->filename);
-       strcpy (info_v, info);
-       strcat (info_v, RCSEXT);
+       (void) xasprintf (&info_v, "%s/%s%s", adm, fileptr->filename, RCSEXT);
        if (isfile (info_v))
            /* We will check out this file in the mkmodules step.
               Nothing else is required.  */
-           ;
+           free (info_v);
        else
        {
            int retcode;
+           (void) xasprintf (&info, "%s/%s", adm, fileptr->filename);
 
            if (!isfile (info))
            {
@@ -911,14 +908,14 @@
            if (retcode != 0)
                /* add_rcs_file already printed an error message.  */
                err = 1;
+           free (info_v);
+           free (info);
        }
     }
 
     /* Turn on history logging by default.  The user can remove the file
        to disable it.  */
-    strcpy (info, adm);
-    strcat (info, "/");
-    strcat (info, CVSROOTADM_HISTORY);
+    (void) xasprintf (&info, "%s/%s", adm, CVSROOTADM_HISTORY);
     if (!isfile (info))
     {
        FILE *fp;
@@ -934,9 +931,8 @@
     }
 
     /* Make an empty val-tags file to prevent problems creating it later.  */
-    strcpy (info, adm);
-    strcat (info, "/");
-    strcat (info, CVSROOTADM_VALTAGS);
+    free (info);
+    (void) xasprintf (&info, "%s/%s", adm, CVSROOTADM_VALTAGS);
     if (!isfile (info))
     {
        FILE *fp;
@@ -952,7 +948,6 @@
     }
 
     free (info);
-    free (info_v);
 
     mkmodules (adm);
 
Index: src/modules.c
===================================================================
RCS file: /cvs/ccvs/src/modules.c,v
retrieving revision 1.75
diff -u -u -r1.75 modules.c
--- src/modules.c       5 Oct 2003 00:37:16 -0000       1.75
+++ src/modules.c       25 Oct 2003 02:17:35 -0000
@@ -69,10 +69,7 @@
        error (0, 0, "must set the CVSROOT environment variable");
        error (1, 0, "or specify the '-d' global option");
     }
-    mfile = xmalloc (strlen (current_parsed_root->directory)
-                    + sizeof (CVSROOTADM)
-                    + sizeof (CVSROOTADM_MODULES) + 3);
-    (void) sprintf (mfile, "%s/%s/%s", current_parsed_root->directory,
+    (void) xasprintf (&mfile, "%s/%s/%s", current_parsed_root->directory,
                    CVSROOTADM, CVSROOTADM_MODULES);
     retval = dbm_open (mfile, O_RDONLY, 0666);
     free (mfile);
@@ -95,10 +92,10 @@
  * It runs the post checkout or post tag proc from the modules file
  */
 int
-do_module (DBM *db, char *mname, enum mtype m_type, char *msg,
-           CALLBACKPROC callback_proc, char *where, int shorten,
+do_module (DBM *db, const char *rmname, enum mtype m_type, const char *msg,
+           CALLBACKPROC callback_proc, const char *where, int shorten,
            int local_specified, int run_module_prog, int build_dirs,
-           char *extra_arg)
+           const char *extra_arg)
 {
     char *checkout_prog = NULL;
     char *export_prog = NULL;
@@ -106,6 +103,7 @@
     struct saved_cwd cwd;
     int cwd_saved = 0;
     char *line;
+    char *mname = xstrdup (rmname);
     int modargc;
     int xmodargc;
     char **modargv = NULL;
@@ -150,7 +148,7 @@
      */
 
     /* look it up as a module name */
-    key.dptr = mname;
+    key.dptr = (char *)mname;
     key.dsize = strlen (key.dptr);
     if (db != NULL)
        val = dbm_fetch (db, key);
@@ -184,22 +182,20 @@
        int is_found = 0;
 
        /* check to see if mname is a directory or file */
-       file = xmalloc (strlen (current_parsed_root->directory)
-                       + strlen (mname) + sizeof(RCSEXT) + 2);
-       (void) sprintf (file, "%s/%s", current_parsed_root->directory, mname);
-       attic_file = xmalloc (strlen (current_parsed_root->directory)
-                             + strlen (mname)
-                             + sizeof (CVSATTIC) + sizeof (RCSEXT) + 3);
+       (void) xasprintf (&file, "%s/%s", current_parsed_root->directory,
+           mname);
        if ((acp = strrchr (mname, '/')) != NULL)
        {
            *acp = '\0';
-           (void) sprintf (attic_file, "%s/%s/%s/%s%s", 
current_parsed_root->directory,
-                           mname, CVSATTIC, acp + 1, RCSEXT);
+           (void) xasprintf (&attic_file, "%s/%s/%s/%s%s",
+               current_parsed_root->directory,
+               mname, CVSATTIC, acp + 1, RCSEXT);
            *acp = '/';
        }
        else
-           (void) sprintf (attic_file, "%s/%s/%s%s", 
current_parsed_root->directory,
-                           CVSATTIC, mname, RCSEXT);
+           (void) xasprintf (&attic_file, "%s/%s/%s%s",
+               current_parsed_root->directory,
+               CVSATTIC, mname, RCSEXT);
 
        if (isdir (file))
        {
@@ -210,7 +206,9 @@
        }
        else
        {
-           (void) strcat (file, RCSEXT);
+           free (file);
+           (void) xasprintf (&file, "%s/%s%s", current_parsed_root->directory,
+               mname, RCSEXT);
            if (isfile (file) || isfile (attic_file))
            {
                /* if mname was a file, we have to split it into "dir file" */
@@ -288,7 +286,7 @@
     {
        /* Make the slash the new end of the string temporarily */
        *cp = '\0';
-       key.dptr = mname;
+       key.dptr = (char *)mname;
        key.dsize = strlen (key.dptr);
 
        /* do the lookup */
@@ -375,10 +373,7 @@
      */
 
     /* Put the value on a line with XXX prepended for getopt to eat */
-    line = xmalloc (strlen (value) + 5);
-    strcpy(line, "XXX ");
-    strcpy(line + 4, value);
-
+    (void) xasprintf (&line, "XXX %s", value);
     /* turn the line into an argv[] array */
     line2argv (&xmodargc, &xmodargv, line, " \t");
     free (line);
@@ -491,7 +486,7 @@
         * we had nothing but special options, so we must
         * make the appropriate directory and cd to it
         */
-       char *dir;
+       const char *dir;
 
        if (!build_dirs)
            goto do_special;
@@ -555,24 +550,16 @@
        (directly or via the callback_proc).  */
     if (server_active && spec_opt != NULL)
     {
-       char *change_to;
+       const char *change_to;
 
        change_to = where ? where : (mwhere ? mwhere : mname);
        server_dir_to_restore = server_dir;
        restore_server_dir = 1;
-       server_dir =
-           xmalloc ((server_dir_to_restore != NULL
-                     ? strlen (server_dir_to_restore)
-                     : 0)
-                    + strlen (change_to)
-                    + 5);
-       server_dir[0] = '\0';
        if (server_dir_to_restore != NULL)
-       {
-           strcat (server_dir, server_dir_to_restore);
-           strcat (server_dir, "/");
-       }
-       strcat (server_dir, change_to);
+           (void) xasprintf (&server_dir, "%s/%s", server_dir_to_restore,
+               change_to);
+       else
+           server_dir = xstrdup (change_to);
     }
 #endif
 
@@ -638,14 +625,12 @@
            char *real_prog = NULL;
            char *prog = (m_type == TAG ? tag_prog :
                          (m_type == CHECKOUT ? checkout_prog : export_prog));
-           char *real_where = (where != NULL ? where : mwhere);
+           const char *real_where = (where != NULL ? where : mwhere);
            char *expanded_path;
 
            if ((*prog != '/') && (*prog != '.'))
            {
-               real_prog = xmalloc (strlen (real_where) + strlen (prog)
-                                    + 10);
-               (void) sprintf (real_prog, "%s/%s", real_where, prog);
+               (void) xasprintf (&real_prog, "%s/%s", real_where, prog);
                if (isfile (real_prog))
                    prog = real_prog;
            }
@@ -678,6 +663,7 @@
     }
 
  do_module_return:
+    free (mname);
     /* clean up */
     if (xmodargv != NULL)
        free_names (&xmodargc, xmodargv);
@@ -878,21 +864,18 @@
        char *line;
 
        /* Print module name (and status, if wanted) */
-       line = xmalloc (strlen (s_h->modname) + 15);
-       sprintf (line, "%-12s", s_h->modname);
+       (void) xasprintf (&line, "%-12s", s_h->modname);
        cvs_output (line, 0);
        free (line);
        if (status)
        {
-           line = xmalloc (strlen (s_h->status) + 15);
-           sprintf (line, " %-11s", s_h->status);
+           xasprintf (&line, " %-11s", s_h->status);
            cvs_output (line, 0);
            free (line);
        }
 
-       line = xmalloc (strlen (s_h->modname) + strlen (s_h->rest) + 15);
        /* Parse module file entry as command line and print options */
-       (void) sprintf (line, "%s %s", s_h->modname, s_h->rest);
+       (void) xasprintf (&line, "%s %s", s_h->modname, s_h->rest);
        line2argv (&moduleargc, &moduleargv, line, " \t");
        free (line);
        argc = moduleargc;
Index: src/parseinfo.c
===================================================================
RCS file: /cvs/ccvs/src/parseinfo.c,v
retrieving revision 1.49
diff -u -u -r1.49 parseinfo.c
--- src/parseinfo.c     19 Aug 2003 13:35:15 -0000      1.49
+++ src/parseinfo.c     25 Oct 2003 02:17:35 -0000
@@ -19,7 +19,8 @@
  * Return 0 for success, -1 if there was not an INFOFILE, and >0 for failure.
  */
 int
-Parse_Info(char *infofile, char *repository, CALLPROC callproc, int opt, void 
*closure)
+Parse_Info(const char *infofile, const char *repository, CALLPROC callproc,
+    int opt, void *closure)
 {
     int err = 0;
     FILE *fp_info;
@@ -30,7 +31,8 @@
     int default_line = 0;
     char *expanded_value;
     int callback_done, line_number;
-    char *cp, *exp, *value, *srepos;
+    char *cp, *exp, *value;
+    const char *srepos;
     const char *regex_err;
 
     if (current_parsed_root == NULL)
@@ -41,11 +43,7 @@
     }
 
     /* find the info file and open it */
-    infopath = xmalloc (strlen (current_parsed_root->directory)
-                       + strlen (infofile)
-                       + sizeof (CVSROOTADM)
-                       + 3);
-    (void) sprintf (infopath, "%s/%s/%s", current_parsed_root->directory,
+    (void) xasprintf (&infopath, "%s/%s/%s", current_parsed_root->directory,
                    CVSROOTADM, infofile);
     fp_info = CVS_FOPEN (infopath, "r");
     if (fp_info == NULL)
@@ -210,7 +208,7 @@
    Returns 0 for success, negative value for failure.  Call
    error(0, ...) on errors in addition to the return value.  */
 int
-parse_config (char *cvsroot)
+parse_config (const char *cvsroot)
 {
     char *infopath;
     FILE *fp_info;
@@ -228,21 +226,8 @@
        return 0;
     parsed = 1;
 
-    infopath = xmalloc (strlen (cvsroot)
-                       + sizeof (CVSROOTADM_CONFIG)
-                       + sizeof (CVSROOTADM)
-                       + 10);
-    if (infopath == NULL)
-    {
-       error (0, 0, "out of memory; cannot allocate infopath");
-       goto error_return;
-    }
-
-    strcpy (infopath, cvsroot);
-    strcat (infopath, "/");
-    strcat (infopath, CVSROOTADM);
-    strcat (infopath, "/");
-    strcat (infopath, CVSROOTADM_CONFIG);
+    (void) xasprintf (&infopath, "%s/%s/%s", cvsroot, CVSROOTADM,
+       CVSROOTADM_CONFIG);
 
     fp_info = CVS_FOPEN (infopath, "r");
     if (fp_info == NULL)
Index: src/patch.c
===================================================================
RCS file: /cvs/ccvs/src/patch.c,v
retrieving revision 1.91
diff -u -u -r1.91 patch.c
--- src/patch.c 24 Oct 2003 15:38:20 -0000      1.91
+++ src/patch.c 25 Oct 2003 02:17:36 -0000
@@ -16,13 +16,13 @@
 #include "getline.h"
 
 static RETSIGTYPE patch_cleanup (void);
-static Dtype patch_dirproc (void *callerdat, char *dir,
-                                  char *repos, char *update_dir,
+static Dtype patch_dirproc (void *callerdat, const char *dir,
+                                  const char *repos, const char *update_dir,
                                   List *entries);
 static int patch_fileproc (void *callerdat, struct file_info *finfo);
-static int patch_proc (int argc, char **argv, char *xwhere,
-                      char *mwhere, char *mfile, int shorten,
-                      int local_specified, char *mname, char *msg);
+static int patch_proc (int argc, char **argv, const char *xwhere,
+                      const char *mwhere, const char *mfile, int shorten,
+                      int local_specified, const char *mname, const char *msg);
 
 static int force_tag_match = 1;
 static int patch_short = 0;
@@ -146,8 +146,7 @@
                    error (1, 0, "must specify a version number to -V");
                if (options)
                    free (options);
-               options = xmalloc (strlen (optarg) + 1 + 2);    /* for the -V */
-               (void) sprintf (options, "-V%s", optarg);
+               (void) xasprintf (&options, "-V%s", optarg);
 #endif
                break;
            case 'u':
@@ -250,7 +249,8 @@
     db = open_module ();
     for (i = 0; i < argc; i++)
        err += do_module (db, argv[i], PATCH, "Patching", patch_proc,
-                         (char *) NULL, 0, local, 0, 0, (char *) NULL);
+                         (const char *) NULL, 0, local, 0, 0,
+                         (const char *) NULL);
     close_module (db);
     free (options);
     patch_cleanup ();
@@ -262,8 +262,9 @@
  */
 /* ARGSUSED */
 static int
-patch_proc (int argc, char **argv, char *xwhere, char *mwhere, char *mfile,
-            int shorten, int local_specified, char *mname, char *msg)
+patch_proc (int argc, char **argv, const char *xwhere, const char *mwhere,
+    const char *mfile, int shorten, int local_specified, const char *mname,
+    const char *msg)
 {
     char *myargv[2];
     int err = 0;
@@ -274,60 +275,8 @@
     TRACE ( TRACE_FUNCTION, "patch_proc ( %s, %s, %s, %d, %d, %s, %s )",
            xwhere, mwhere, mfile, shorten, local_specified, mname, msg );
 
-    repository = xmalloc (strlen (current_parsed_root->directory)
-                          + strlen (argv[0])
-                          + (mfile == NULL ? 0 : strlen (mfile) + 1) + 2);
-    (void) sprintf (repository, "%s/%s",
-                    current_parsed_root->directory, argv[0]);
-    where = xmalloc (strlen (argv[0])
-                     + (mfile == NULL ? 0 : strlen (mfile) + 1)
-                    + 1);
-    (void) strcpy (where, argv[0]);
-
-    /* if mfile isn't null, we need to set up to do only part of the module */
-    if (mfile != NULL)
-    {
-       char *cp;
-       char *path;
-
-       /* if the portion of the module is a path, put the dir part on repos */
-       if ((cp = strrchr (mfile, '/')) != NULL)
-       {
-           *cp = '\0';
-           (void) strcat (repository, "/");
-           (void) strcat (repository, mfile);
-           (void) strcat (where, "/");
-           (void) strcat (where, mfile);
-           mfile = cp + 1;
-       }
-
-       /* take care of the rest */
-       path = xmalloc (strlen (repository) + strlen (mfile) + 2);
-       (void) sprintf (path, "%s/%s", repository, mfile);
-       if (isdir (path))
-       {
-           /* directory means repository gets the dir tacked on */
-           (void) strcpy (repository, path);
-           (void) strcat (where, "/");
-           (void) strcat (where, mfile);
-       }
-       else
-       {
-           myargv[0] = argv[0];
-           myargv[1] = mfile;
-           argc = 2;
-           argv = myargv;
-       }
-       free (path);
-    }
-
-    /* cd to the starting repository */
-    if (CVS_CHDIR (repository) < 0)
-    {
-       error (0, errno, "cannot chdir to %s", repository);
-       free (repository);
-       return (1);
-    }
+    if (get_repository (&repository, &where, mfile, &argc, &argv, myargv) == 0)
+       return -1;
 
     if (force_tag_match)
        which = W_REPOS | W_ATTIC;
@@ -399,8 +348,7 @@
     if ((rcsfile->flags & VALID) && (rcsfile->flags & INATTIC))
        isattic = 1;
 
-    rcs = xmalloc (strlen (finfo->file) + sizeof (RCSEXT) + 5);
-    (void) sprintf (rcs, "%s%s", finfo->file, RCSEXT);
+    (void) xasprintf (&rcs, "%s%s", finfo->file, RCSEXT);
 
     /* if vers_head is NULL, may have been removed from the release */
     if (isattic && rev2 == NULL && date2 == NULL)
@@ -643,8 +591,7 @@
            assert (current_parsed_root != NULL);
            assert (current_parsed_root->directory != NULL);
            {
-               strippath = xmalloc (strlen (current_parsed_root->directory) + 
2);
-               (void) sprintf (strippath, "%s/", 
current_parsed_root->directory);
+               (void) xasprintf (&strippath, "%s/", 
current_parsed_root->directory);
            }
            /*else
                strippath = xstrdup (REPOS_STRIP); */
@@ -653,19 +600,13 @@
            free (strippath);
            if (vers_tag != NULL)
            {
-               file1 = xmalloc (strlen (finfo->fullname)
-                                + strlen (vers_tag)
-                                + 10);
-               (void) sprintf (file1, "%s:%s", finfo->fullname, vers_tag);
+               (void) xasprintf (&file1, "%s:%s", finfo->fullname, vers_tag);
            }
            else
            {
                file1 = xstrdup (DEVNULL);
            }
-           file2 = xmalloc (strlen (finfo->fullname)
-                            + (vers_head != NULL ? strlen (vers_head) : 10)
-                            + 10);
-           (void) sprintf (file2, "%s:%s", finfo->fullname,
+           (void) xasprintf (&file2, "%s:%s", finfo->fullname,
                            vers_head ? vers_head : "removed");
 
            /* Note that the string "diff" is specified by POSIX (for -c)
@@ -748,7 +689,8 @@
  */
 /* ARGSUSED */
 static Dtype
-patch_dirproc (void *callerdat, char *dir, char *repos, char *update_dir, List 
*entries)
+patch_dirproc (void *callerdat, const char *dir, const char *repos,
+    const char *update_dir, List *entries)
 {
     if (!quiet)
        error (0, 0, "Diffing %s", update_dir);
Index: src/rcs.c
===================================================================
RCS file: /cvs/ccvs/src/rcs.c,v
retrieving revision 1.292
diff -u -u -r1.292 rcs.c
--- src/rcs.c   8 Oct 2003 18:57:10 -0000       1.292
+++ src/rcs.c   25 Oct 2003 02:17:37 -0000
@@ -61,7 +61,8 @@
 };
 
 static RCSNode *RCS_parsercsfile_i (FILE * fp, const char *rcsfile);
-static char *RCS_getdatebranch (RCSNode * rcs, char *date, char *branch);
+static char *RCS_getdatebranch (RCSNode * rcs, const char *date,
+                               const char *branch);
 static void rcsbuf_open (struct rcsbuffer *, FILE *fp,
                                const char *filename, unsigned long pos);
 static void rcsbuf_close (struct rcsbuffer *);
@@ -118,7 +119,7 @@
 static int putrcsfield_proc (Node *, void *);
 static int putsymbol_proc (Node *, void *);
 static void RCS_copydeltas (RCSNode *, FILE *, struct rcsbuffer *,
-                                  FILE *, Deltatext *, char *);
+                                  FILE *, Deltatext *, const char *);
 static int count_delta_actions (Node *, void *);
 static void putdeltatext (FILE *, Deltatext *);
 
@@ -217,19 +218,16 @@
     char *retval;
 
     /* First, try to find the file as cased. */
-    retval = xmalloc (strlen (repository)
-                      + sizeof (CVSATTIC)
-                      + strlen (file)
-                      + sizeof (RCSEXT)
-                      + 3);
-    sprintf (retval, "%s/%s%s", repository, file, RCSEXT);
+    (void) xasprintf (&retval, "%s/%s%s", repository, file, RCSEXT);
     if (isreadable (retval))
     {
        if (inattic)
            *inattic = 0;
        return retval;
     }
-    sprintf (retval, "%s/%s/%s%s", repository, CVSATTIC, file, RCSEXT);
+    free (retval);
+    (void) xasprintf (&retval, "%s/%s/%s%s", repository, CVSATTIC, file,
+       RCSEXT);
     if (isreadable (retval))
     {
        if (inattic)
@@ -245,9 +243,7 @@
     if (ign_case)
     {
        /* Allocate space and add the RCS extension */
-       rcsfile = xmalloc (strlen (file)
-                          + sizeof (RCSEXT));
-       sprintf (rcsfile, "%s%s", file, RCSEXT);
+       (void) xasprintf (&rcsfile, "%s%s", file, RCSEXT);
 
 
        /* Search in the top dir given */
@@ -259,10 +255,7 @@
        }
 
        /* Search in the Attic */
-       dir = xmalloc (strlen (repository)
-                      + sizeof (CVSATTIC)
-                      + 2);
-       sprintf (dir, "%s/%s", repository, CVSATTIC);
+       (void) xasprintf (&dir, "%s/%s", repository, CVSATTIC);
 
        if ((retval = locate_file_in_dir (dir, rcsfile)) != NULL
            && inattic)
@@ -353,6 +346,7 @@
 {
     FILE *fp;
     RCSNode *rcs;
+    char path[1024];
 
     /* We're creating a new RCSNode, so there is no hope of finding it
        in the cache.  */
@@ -2171,7 +2165,8 @@
  * The result is returned; null-string if error.
  */
 char *
-RCS_getversion (RCSNode *rcs, char *tag, char *date, int force_tag_match, int 
*simple_tag)
+RCS_getversion (RCSNode *rcs, const char *tag, const char *date,
+    int force_tag_match, int *simple_tag)
 {
     if (simple_tag != NULL)
        *simple_tag = 0;
@@ -2222,7 +2217,7 @@
  * return NULL.
  */
 char *
-RCS_tag2rev (RCSNode *rcs, char *tag)
+RCS_tag2rev (RCSNode *rcs, const char *tag)
 {
     char *rev, *pa, *pb;
     int i;
@@ -2273,9 +2268,8 @@
        * the 0 in some other position -- <dan@gasboy.com>
        */ 
        pa = strrchr (rev, '.');
-       pb = xmalloc (strlen (rev) + 3);
        *pa++ = 0;
-       (void) sprintf (pb, "%s.%d.%s", rev, RCS_MAGIC_BRANCH, pa);
+       (void) xasprintf (&pb, "%s.%d.%s", rev, RCS_MAGIC_BRANCH, pa);
        free (rev);
        rev = pb;
        if (RCS_exist_rev (rcs, rev))
@@ -2311,10 +2305,12 @@
  * Returns pointer to newly malloc'd string, or NULL.
  */
 char *
-RCS_gettag (RCSNode *rcs, char *symtag, int force_tag_match, int *simple_tag)
+RCS_gettag (RCSNode *rcs, const char *symtag, int force_tag_match,
+    int *simple_tag)
 {
-    char *tag = symtag;
-    int tag_allocated = 0;
+    const char *tag = symtag;
+    char *free_tag = NULL;
+    size_t len;
 
     if (simple_tag != NULL)
        *simple_tag = 0;
@@ -2346,8 +2342,7 @@
            int dots;
            char *magic, *branch, *cp;
 
-           tag = version;
-           tag_allocated = 1;
+           tag = free_tag = version;
 
            /*
             * If this is a magic revision, we turn it into either its
@@ -2363,21 +2358,21 @@
                    cp--;
 
                /* see if we have .magic-branch. (".0.") */
-               magic = xmalloc (strlen (tag) + 1);
-               (void) sprintf (magic, ".%d.", RCS_MAGIC_BRANCH);
+               (void) xasprintf (&magic, ".%d.", RCS_MAGIC_BRANCH);
                if (strncmp (magic, cp, strlen (magic)) == 0)
                {
                    /* it's magic.  See if the branch exists */
                    *cp = '\0';         /* turn it into a revision */
-                   (void) sprintf (magic, "%s.%s", tag, branch);
+                   free (magic);
+                   (void) xasprintf (&magic, "%s.%s", tag, branch);
                    branch = RCS_getbranch (rcs, magic, 1);
                    free (magic);
                    if (branch != NULL)
                    {
-                       free (tag);
+                       free (free_tag);
                        return (branch);
                    }
-                   return (tag);
+                   return (free_tag);
                }
                free (magic);
            }
@@ -2392,6 +2387,8 @@
        }
     }
 
+    if (free_tag == NULL)
+       free_tag = xstrdup (tag);
     /*
      * numeric tag processing:
      *         1) revision number - just return it
@@ -2399,17 +2396,16 @@
      */
 
     /* strip trailing dots */
-    while (tag[strlen (tag) - 1] == '.')
-       tag[strlen (tag) - 1] = '\0';
+    while (free_tag[len = strlen (free_tag) - 1] == '.')
+       free_tag[len] = '\0';
 
-    if ((numdots (tag) & 1) == 0)
+    if ((numdots (free_tag) & 1) == 0)
     {
        char *branch;
 
        /* we have a branch tag, so we need to walk the branch */
-       branch = RCS_getbranch (rcs, tag, force_tag_match);
-       if (tag_allocated)
-           free (tag);
+       branch = RCS_getbranch (rcs, free_tag, force_tag_match);
+       free (free_tag);
        return branch;
     }
     else
@@ -2417,7 +2413,7 @@
        Node *p;
 
        /* we have a revision tag, so make sure it exists */
-       p = findnode (rcs->versions, tag);
+       p = findnode (rcs->versions, free_tag);
        if (p != NULL)
        {
            /* We have found a numeric revision for the revision tag.
@@ -2429,15 +2425,12 @@
               without calling co?  */
            if (simple_tag != NULL)
                *simple_tag = 1;
-           if (! tag_allocated)
-               tag = xstrdup (tag);
-           return (tag);
+           return (free_tag);
        }
        else
        {
            /* The revision wasn't there, so return the head or NULL */
-           if (tag_allocated)
-               free (tag);
+           free (free_tag);
            if (force_tag_match)
                return (NULL);
            else
@@ -2470,7 +2463,7 @@
  */
 static char *check_rev;
 char *
-RCS_magicrev (RCSNode *rcs, char *rev)
+RCS_magicrev (RCSNode *rcs, const char *rev)
 {
     int rev_num;
     char *xrev, *test_branch, *local_branch_num;
@@ -2586,8 +2579,7 @@
            cp--;
 
        /* see if we have .magic-branch. (".0.") */
-       magic = xmalloc (strlen (version) + 1);
-       (void) sprintf (magic, ".%d.", RCS_MAGIC_BRANCH);
+       (void) xasprintf (&magic, ".%d.", RCS_MAGIC_BRANCH);
        if (strncmp (magic, cp, strlen (magic)) == 0)
        {
            free (magic);
@@ -2632,13 +2624,13 @@
            cp--;
 
        /* see if we have .magic-branch. (".0.") */
-       magic = xmalloc (strlen (version) + 1);
-       (void) sprintf (magic, ".%d.", RCS_MAGIC_BRANCH);
+       (void) xasprintf (&magic, ".%d.", RCS_MAGIC_BRANCH);
        if (strncmp (magic, cp, strlen (magic)) == 0)
        {
            /* yep.  it's magic.  now, construct the real branch */
            *cp = '\0';                 /* turn it into a revision */
-           (void) sprintf (magic, "%s.%s", version, branch);
+           free (magic);
+           (void) xasprintf (&magic, "%s.%s", version, branch);
            free (version);
            return (magic);
        }
@@ -2654,7 +2646,7 @@
  * Returns NULL or a newly malloc'd string.
  */
 char *
-RCS_getbranch (RCSNode *rcs, char *tag, int force_tag_match)
+RCS_getbranch (RCSNode *rcs, const char *tag, int force_tag_match)
 {
     Node *p, *head;
     RCSVers *vn;
@@ -2674,9 +2666,7 @@
     /* trunk processing is the special case */
     if (cp == NULL)
     {
-       xtag = xmalloc (strlen (tag) + 1 + 1);  /* +1 for an extra . */
-       (void) strcpy (xtag, tag);
-       (void) strcat (xtag, ".");
+       (void) xasprintf (&xtag, "%s.", tag);
        for (cp = rcs->head; cp != NULL;)
        {
            if (strncmp (xtag, cp, strlen (xtag)) == 0)
@@ -2726,9 +2716,7 @@
     vn = (RCSVers *) p->data;
     if (vn->branches == NULL)
        return (NULL);
-    xtag = xmalloc (strlen (tag) + 1 + 1);     /* 1 for the extra '.' */
-    (void) strcpy (xtag, tag);
-    (void) strcat (xtag, ".");
+    (void) xasprintf (&xtag, "%s.", tag);
     head = vn->branches->list;
     for (p = head->next; p != head; p = p->next)
        if (strncmp (p->key, xtag, strlen (xtag)) == 0)
@@ -2772,7 +2760,7 @@
    isn't found.  */
 
 char *
-RCS_branch_head (RCSNode *rcs, char *rev)
+RCS_branch_head (RCSNode *rcs, const char *rev)
 {
     char *num;
     char *br;
@@ -2900,7 +2888,7 @@
  * funky stuff and follow the vendor branch maybe
  */
 char *
-RCS_getdate (RCSNode *rcs, char *date, int force_tag_match)
+RCS_getdate (RCSNode *rcs, const char *date, int force_tag_match)
 {
     char *cur_rev = NULL;
     char *retval = NULL;
@@ -3000,7 +2988,7 @@
  * the specified date and time (return the rev or NULL)
  */
 static char *
-RCS_getdatebranch (RCSNode *rcs, char *date, char *branch)
+RCS_getdatebranch (RCSNode *rcs, const char *date, const char *branch)
 {
     char *cur_rev = NULL;
     char *cp;
@@ -3039,9 +3027,7 @@
        return xstrdup (cur_rev);
 
     /* walk the branches list looking for the branch number */
-    xbranch = xmalloc (strlen (branch) + 1 + 1); /* +1 for the extra dot */
-    (void) strcpy (xbranch, branch);
-    (void) strcat (xbranch, ".");
+    (void) xasprintf (&xbranch, "%s.", branch);
     for (p = vers->branches->list->next; p != vers->branches->list; p = 
p->next)
        if (strncmp (p->key, xbranch, strlen (xbranch)) == 0)
            break;
@@ -3082,7 +3068,7 @@
  * 2000, when years go from 2-digit to full format.
  */
 int
-RCS_datecmp (char *date1, char *date2)
+RCS_datecmp (const char *date1, const char *date2)
 {
     int length_diff = strlen (date1) - strlen (date2);
 
@@ -3101,7 +3087,7 @@
    then it must point to MAXDATELEN characters, and we store the same
    return value there in DATEFORM format.  */
 time_t
-RCS_getrevtime (RCSNode *rcs, char *rev, char *date, int fudge)
+RCS_getrevtime (RCSNode *rcs, const char *rev, char *date, int fudge)
 {
     char tdate[MAXDATELEN];
     struct tm xtm, *ftm;
@@ -3342,7 +3328,7 @@
  * call error.
  */
 int 
-RCS_valid_rev (char *rev)
+RCS_valid_rev (const char *rev)
 {
    char last, c;
    last = *rev++;
@@ -3401,7 +3387,7 @@
 
 /* Set keyword expansion mode to EXPAND.  For example "b" for binary.  */
 void
-RCS_setexpand (RCSNode *rcs, char *expand)
+RCS_setexpand (RCSNode *rcs, const char *expand)
 {
     /* Since RCS_parsercsfile_i now reads expand, don't need to worry
        about RCS_reparsercsfile.  */
@@ -3688,15 +3674,8 @@
                        path = last_component (rcs->path);
                    path = escape_keyword_value (path, &free_path);
                    date = printable_date (ver->date);
-                   value = xmalloc (strlen (path)
-                                    + strlen (ver->version)
-                                    + strlen (date)
-                                    + strlen (ver->author)
-                                    + strlen (ver->state)
-                                    + (locker == NULL ? 0 : strlen (locker))
-                                    + 20);
 
-                   sprintf (value, "%s %s %s %s %s%s%s",
+                   (void) xasprintf (&value, "%s %s %s %s %s%s%s",
                             path, ver->version, date, ver->author,
                             ver->state,
                             locker != NULL ? " " : "",
@@ -4019,9 +3998,11 @@
    comments in RCS_checkin for some issues about this. -twp */
 
 int
-RCS_checkout (RCSNode *rcs, char *workfile, char *rev, char *nametag, char 
*options, char *sout, RCSCHECKOUTPROC pfn, void *callerdat)
+RCS_checkout (RCSNode *rcs, const char *workfile, const char *rev,
+    const char *nametag, const char *options, const char *sout,
+    RCSCHECKOUTPROC pfn, void *callerdat)
 {
-    int free_rev = 0;
+    char *free_rev = NULL;
     enum kflag expand;
     FILE *fp, *ofp;
     struct stat sb;
@@ -4066,10 +4047,9 @@
        branch.  */
     if (rev != NULL && (numdots (rev) & 1) == 0)
     {
-       rev = RCS_getbranch (rcs, rev, 1);
+       rev = free_rev = RCS_getbranch (rcs, rev, 1);
        if (rev == NULL)
            error (1, 0, "internal error: bad branch tag in checkout");
-       free_rev = 1;
     }
 
     if (rev == NULL || STREQ (rev, rcs->head))
@@ -4101,7 +4081,7 @@
        {
            error (0, 0, "internal error: cannot find head text");
            if (free_rev)
-               free (rev);
+               free (free_rev);
            return 1;
        }
 
@@ -4216,7 +4196,7 @@
            if (free_value)
                free (value);
            if (free_rev)
-               free (rev);
+               free (free_rev);
            return 0;
        }
 
@@ -4267,7 +4247,7 @@
                    if (free_value)
                        free (value);
                    if (free_rev)
-                       free (rev);
+                       free (free_rev);
                    return 0;
                }
            }
@@ -4339,7 +4319,7 @@
     }
 
     if (free_rev)
-       free (rev);
+       free (free_rev);
 
     if (log != NULL)
     {
@@ -4756,9 +4736,7 @@
        {
            /* We have to create the first branch on this node, which means
               appending ".2" to the revision number. */
-           newrevnum = (char *) xmalloc (strlen (branch) + 3);
-           strcpy (newrevnum, branch);
-           strcat (newrevnum, ".2");
+           (void) xasprintf (&newrevnum, "%s.2", branch);
        }
        else
        {
@@ -4847,7 +4825,8 @@
    or zero for success.  */
 
 int
-RCS_checkin (RCSNode *rcs, char *workfile, char *message, char *rev, int flags)
+RCS_checkin (RCSNode *rcs, const char *workfile, const char *message,
+    const char *rev, int flags)
 {
     RCSVers *delta, *commitpt;
     Deltatext *dtext;
@@ -4856,7 +4835,8 @@
     char *diffopts;
     size_t bufsize;
     int buflen, chtextlen;
-    int status, checkin_quiet, allocated_workfile;
+    int status, checkin_quiet;
+    char *free_workfile = NULL;
     struct tm *ftm;
     time_t modtime;
     int adding_branch = 0;
@@ -4871,16 +4851,14 @@
 
     /* Get basename of working file.  Is there a library function to
        do this?  I couldn't find one. -twp */
-    allocated_workfile = 0;
     if (workfile == NULL)
     {
        char *p;
        int extlen = strlen (RCSEXT);
-       workfile = xstrdup (last_component (rcs->path));
-       p = workfile + (strlen (workfile) - extlen);
+       workfile = free_workfile = xstrdup (last_component (rcs->path));
+       p = free_workfile + (strlen (free_workfile) - extlen);
        assert (strncmp (p, RCSEXT, extlen) == 0);
        *p = '\0';
-       allocated_workfile = 1;
     }
 
     /* If the filename is a symbolic link, follow it and replace it
@@ -4914,8 +4892,7 @@
     else
        (void) time (&modtime);
     ftm = gmtime (&modtime);
-    delta->date = (char *) xmalloc (MAXDATELEN);
-    (void) sprintf (delta->date, DATEFORM,
+    (void) xasprintf (&delta->date, DATEFORM,
                    ftm->tm_year + (ftm->tm_year < 100 ? 0 : 1900),
                    ftm->tm_mon + 1, ftm->tm_mday, ftm->tm_hour,
                    ftm->tm_min, ftm->tm_sec);
@@ -5023,9 +5000,7 @@
            newrev = xstrdup ("1.1");
        else if (numdots (rev) == 0)
        {
-           newrev = (char *) xmalloc (strlen (rev) + 3);
-           strcpy (newrev, rev);
-           strcat (newrev, ".1");
+           (void) xasprintf (&newrev, "%s.1", rev);
        }
        else
            newrev = xstrdup (rev);
@@ -5445,8 +5420,8 @@
        cvs_output ("done\n", 5);
 
  checkin_done:
-    if (allocated_workfile)
-       free (workfile);
+    if (free_workfile)
+       free (free_workfile);
 
     if (commitpt != NULL && commitpt->text != NULL)
     {
@@ -5477,7 +5452,8 @@
    the same as the contents of the file, 1 if they are different.  */
 
 int
-RCS_cmp_file (RCSNode *rcs, char *rev1, char **rev1_cache, char *rev2, char 
*options, const char *filename)
+RCS_cmp_file (RCSNode *rcs, const char *rev1, char **rev1_cache,
+    const char *rev2, const char *options, const char *filename)
 {
     int binary;
 
@@ -5750,7 +5726,7 @@
    about. */
 
 int
-RCS_lock (RCSNode *rcs, char *rev, int lock_quiet)
+RCS_lock (RCSNode *rcs, const char *rev, int lock_quiet)
 {
     List *locks;
     Node *p;
@@ -5841,7 +5817,7 @@
    queries the user about whether or not to break the lock. */
 
 int
-RCS_unlock (RCSNode *rcs, char *rev, int unlock_quiet)
+RCS_unlock (RCSNode *rcs, const char *rev, int unlock_quiet)
 {
     Node *lock;
     List *locks;
@@ -5949,7 +5925,7 @@
    FIXME-twp: check syntax of USER to make sure it's a valid id. */
 
 void
-RCS_addaccess (RCSNode *rcs, char *user)
+RCS_addaccess (RCSNode *rcs, const char *user)
 {
     char *access, *a;
 
@@ -5980,7 +5956,7 @@
 /* Remove USER from the access list of RCS. */
 
 void
-RCS_delaccess (RCSNode *rcs, char *user)
+RCS_delaccess (RCSNode *rcs, const char *user)
 {
     char *p, *s;
     int ulen;
@@ -6062,7 +6038,8 @@
    point in ::tag2 and :tag2 is the same and likewise for end points.  */
 
 int
-RCS_delete_revs (RCSNode *rcs, char *tag1, char *tag2, int inclusive)
+RCS_delete_revs (RCSNode *rcs, const char *tag1, const char *tag2,
+    int inclusive)
 {
     char *next;
     Node *nodep;
@@ -6557,7 +6534,7 @@
  * TRUE if there exists a symbolic tag "tag" in file.
  */
 int 
-RCS_exist_tag (RCSNode *rcs, char *tag)
+RCS_exist_tag (RCSNode *rcs, const char *tag)
 {
 
     assert (rcs != NULL);
@@ -6576,7 +6553,7 @@
  * RCS_delete_revs, above.
  */
 int
-RCS_exist_rev (RCSNode *rcs, char *rev)
+RCS_exist_rev (RCSNode *rcs, const char *rev)
 {
 
     assert (rcs != NULL);
@@ -6587,7 +6564,7 @@
     if (findnode(rcs->versions, rev) != 0)
        return 1;
 
-    if (walklist (RCS_symbols(rcs), findtag, rev) != 0)
+    if (walklist (RCS_symbols(rcs), findtag, (void *)rev) != 0)
        return 1;
 
     return 0;
@@ -6961,7 +6938,8 @@
    Return 1 for success.  On failure, call error and return 0.  */
 
 int
-rcs_change_text (const char *name, char *textbuf, size_t textlen, const char 
*diffbuf, size_t difflen, char **retbuf, size_t *retlen)
+rcs_change_text (const char *name, const char *textbuf, size_t textlen,
+    const char *diffbuf, size_t difflen, char **retbuf, size_t *retlen)
 {
     struct linevector lines;
     int ret;
@@ -7031,7 +7009,9 @@
    On error, give a fatal error.  */
 
 void
-RCS_deltas (RCSNode *rcs, FILE *fp, struct rcsbuffer *rcsbuf, char *version, 
enum rcs_delta_op op, char **text, size_t *len, char **log, size_t *loglen)
+RCS_deltas (RCSNode *rcs, FILE *fp, struct rcsbuffer *rcsbuf,
+    const char *version, enum rcs_delta_op op, char **text,
+    size_t *len, char **log, size_t *loglen)
 {
     struct rcsbuffer rcsbuf_local;
     char *branchversion;
@@ -7905,7 +7885,7 @@
    increasing order.) */
 
 static void
-RCS_copydeltas (RCSNode *rcs, FILE *fin, struct rcsbuffer *rcsbufin, FILE 
*fout, Deltatext *newdtext, char *insertpt)
+RCS_copydeltas (RCSNode *rcs, FILE *fin, struct rcsbuffer *rcsbufin, FILE 
*fout, Deltatext *newdtext, const char *insertpt)
 {
     int actions;
     RCSVers *dadmin;
@@ -8308,7 +8288,7 @@
    desired (via RCS_delete_revs, RCS_settag, &c), then call RCS_rewrite.  */
 
 void
-RCS_rewrite (RCSNode *rcs, Deltatext *newdtext, char *insertpt)
+RCS_rewrite (RCSNode *rcs, Deltatext *newdtext, const char *insertpt)
 {
     FILE *fin, *fout;
     struct rcsbuffer rcsbufin;
@@ -8387,16 +8367,11 @@
  * /dev/null to be parsed by patch properly.
  */
 char *
-make_file_label (char *path, char *rev, RCSNode *rcs)
+make_file_label (const char *path, const char *rev, RCSNode *rcs)
 {
     char datebuf[MAXDATELEN + 1];
     char *label;
 
-    label = (char *) xmalloc (strlen (path)
-                             + (rev == NULL ? 0 : strlen (rev) + 1)
-                             + MAXDATELEN
-                             + 2);
-
     if (rev)
     {
        char date[MAXDATELEN + 1];
@@ -8404,7 +8379,7 @@
        assert (strcmp(DEVNULL, path));
        RCS_getrevtime (rcs, rev, datebuf, 0);
        (void) date_to_internet (date, datebuf);
-       (void) sprintf (label, "-L%s\t%s\t%s", path, date, rev);
+       (void) xasprintf (&label, "-L%s\t%s\t%s", path, date, rev);
     }
     else
     {
@@ -8428,7 +8403,7 @@
        }
 
        (void) tm_to_internet (datebuf, wm);
-       (void) sprintf (label, "-L%s\t%s", path, datebuf);
+       (void) xasprintf (&label, "-L%s\t%s", path, datebuf);
     }
     return label;
 }
Index: src/rcs.h
===================================================================
RCS file: /cvs/ccvs/src/rcs.h,v
retrieving revision 1.69
diff -u -u -r1.69 rcs.h
--- src/rcs.h   8 Oct 2003 15:30:25 -0000       1.69
+++ src/rcs.h   25 Oct 2003 02:17:37 -0000
@@ -190,61 +190,62 @@
 extern int RCS_setattic (RCSNode *, int);
 
 char *RCS_check_kflag (const char *arg);
-char *RCS_getdate (RCSNode * rcs, char *date, int force_tag_match);
-char *RCS_gettag (RCSNode * rcs, char *symtag, int force_tag_match,
+char *RCS_getdate (RCSNode * rcs, const char *date, int force_tag_match);
+char *RCS_gettag (RCSNode * rcs, const char *symtag, int force_tag_match,
                  int *simple_tag);
-int RCS_exist_rev (RCSNode *rcs, char *rev);
-int RCS_exist_tag (RCSNode *rcs, char *tag);
-char *RCS_tag2rev (RCSNode *rcs, char *tag);
-char *RCS_getversion (RCSNode * rcs, char *tag, char *date,
+int RCS_exist_rev (RCSNode *rcs, const char *rev);
+int RCS_exist_tag (RCSNode *rcs, const char *tag);
+char *RCS_tag2rev (RCSNode *rcs, const char *tag);
+char *RCS_getversion (RCSNode * rcs, const char *tag, const char *date,
                      int force_tag_match, int *simple_tag);
-char *RCS_magicrev (RCSNode *rcs, char *rev);
+char *RCS_magicrev (RCSNode *rcs, const char *rev);
 int RCS_isbranch (RCSNode *rcs, const char *rev);
 int RCS_nodeisbranch (RCSNode *rcs, const char *tag);
 char *RCS_whatbranch (RCSNode *rcs, const char *tag);
 char *RCS_head (RCSNode * rcs);
-int RCS_datecmp (char *date1, char *date2);
-time_t RCS_getrevtime (RCSNode * rcs, char *rev, char *date, int fudge);
+int RCS_datecmp (const char *date1, const char *date2);
+time_t RCS_getrevtime (RCSNode * rcs, const char *rev, char *date, int fudge);
 List *RCS_symbols (RCSNode *rcs);
 void RCS_check_tag (const char *tag);
-int RCS_valid_rev (char *rev);
+int RCS_valid_rev (const char *rev);
 List *RCS_getlocks (RCSNode *rcs);
 void freercsnode (RCSNode ** rnodep);
-char *RCS_getbranch (RCSNode * rcs, char *tag, int force_tag_match);
-char *RCS_branch_head (RCSNode *rcs, char *rev);
+char *RCS_getbranch (RCSNode * rcs, const char *tag, int force_tag_match);
+char *RCS_branch_head (RCSNode *rcs, const char *rev);
 
 int RCS_isdead (RCSNode *, const char *);
 char *RCS_getexpand (RCSNode *);
-void RCS_setexpand (RCSNode *, char *);
-int RCS_checkout (RCSNode *, char *, char *, char *, char *, char *,
+void RCS_setexpand (RCSNode *, const char *);
+int RCS_checkout (RCSNode *, const char *, const char *, const char *,
+                 const char *, const char *,
                  RCSCHECKOUTPROC, void *);
-int RCS_checkin (RCSNode *rcs, char *workfile, char *message,
-                char *rev, int flags);
-int RCS_cmp_file (RCSNode *, char *, char **, char *, char *,
+int RCS_checkin (RCSNode *rcs, const char *workfile, const char *message,
+                const char *rev, int flags);
+int RCS_cmp_file (RCSNode *, const char *, char **, const char *, const char *,
                  const char * );
 int RCS_settag (RCSNode *, const char *, const char *);
 int RCS_deltag (RCSNode *, const char *);
 int RCS_setbranch (RCSNode *, const char *);
-int RCS_lock (RCSNode *, char *, int);
-int RCS_unlock (RCSNode *, char *, int);
-int RCS_delete_revs (RCSNode *, char *, char *, int);
-void RCS_addaccess (RCSNode *, char *);
-void RCS_delaccess (RCSNode *, char *);
+int RCS_lock (RCSNode *, const char *, int);
+int RCS_unlock (RCSNode *, const char *, int);
+int RCS_delete_revs (RCSNode *, const char *, const char *, int);
+void RCS_addaccess (RCSNode *, const char *);
+void RCS_delaccess (RCSNode *, const char *);
 char *RCS_getaccess (RCSNode *);
-void RCS_rewrite (RCSNode *, Deltatext *, char *);
+void RCS_rewrite (RCSNode *, Deltatext *, const char *);
 void RCS_abandon (RCSNode *);
-int rcs_change_text (const char *, char *, size_t, const char *,
+int rcs_change_text (const char *, const char *, size_t, const char *,
                     size_t, char **, size_t *);
-void RCS_deltas (RCSNode *, FILE *, struct rcsbuffer *, char *,
+void RCS_deltas (RCSNode *, FILE *, struct rcsbuffer *, const char *,
                 enum rcs_delta_op, char **, size_t *,
                 char **, size_t *);
 void RCS_setincexc (const char *arg);
 void RCS_setlocalid (const char *arg);
-char *make_file_label (char *, char *, RCSNode *);
+char *make_file_label (const char *, const char *, RCSNode *);
 
 extern int preserve_perms;
 
 /* From import.c.  */
-extern int add_rcs_file (char *, char *, char *, char *, char *,
-                               char *, char *, int, char **,
-                               char *, size_t, FILE *);
+extern int add_rcs_file (const char *, const char *, const char *, const char 
*,
+                        const char *, const char *, const char *, int, char **,
+                        const char *, size_t, FILE *);
Index: src/rcscmds.c
===================================================================
RCS file: /cvs/ccvs/src/rcscmds.c,v
retrieving revision 1.61
diff -u -u -r1.61 rcscmds.c
--- src/rcscmds.c       5 Oct 2003 00:37:16 -0000       1.61
+++ src/rcscmds.c       25 Oct 2003 02:17:37 -0000
@@ -50,7 +50,8 @@
    On a related note, see the comments at diff_exec, later in this file,
    for more on the diff library.  */
 
-static void RCS_output_diff_options (char *, char *, char *, char *);
+static void RCS_output_diff_options (const char *, const char *, const char *,
+    const char *);
 
 
 /* Stuff to deal with passing arguments the way libdiff.a wants to deal
@@ -73,8 +74,8 @@
 
 static void call_diff_add_arg (const char *);
 static void call_diff_setup (const char *prog);
-static int call_diff (char *out);
-static int call_diff3 (char *out);
+static int call_diff (const char *out);
+static int call_diff3 (const char *out);
 
 static void call_diff_write_output (const char *, size_t);
 static void call_diff_flush_output (void);
@@ -195,7 +196,7 @@
 };
 
 static int
-call_diff (char *out)
+call_diff (const char *out)
 {
     if (out == RUN_TTY)
        return diff_run( call_diff_argc, call_diff_argv, NULL,
@@ -206,7 +207,7 @@
 }
 
 static int
-call_diff3 (char *out)
+call_diff3 (const char *out)
 {
     if (out == RUN_TTY)
        return diff3_run (call_diff_argc, call_diff_argv, NULL,
@@ -221,7 +222,8 @@
 /* Merge revisions REV1 and REV2. */
 
 int
-RCS_merge(RCSNode *rcs, char *path, char *workfile, char *options, char *rev1, 
char *rev2)
+RCS_merge(RCSNode *rcs, const char *path, const char *workfile,
+    const char *options, const char *rev1, const char *rev2)
 {
     char *xrev1, *xrev2;
     char *tmp1, *tmp2;
@@ -361,11 +363,13 @@
    about this--any such features are undocumented in the context of
    CVS, and I'm not sure how important to users.  */
 int
-RCS_exec_rcsdiff(RCSNode *rcsfile, char *opts, char *options, char *rev1, char 
*rev1_cache, char *rev2, char *label1, char *label2, char *workfile)
+RCS_exec_rcsdiff(RCSNode *rcsfile, const char *opts, const char *options,
+    const char *rev1, const char *rev1_cache, const char *rev2,
+    const char *label1, const char *label2, const char *workfile)
 {
     char *tmpfile1 = NULL;
     char *tmpfile2 = NULL;
-    char *use_file1, *use_file2;
+    const char *use_file1, *use_file2;
     int status, retval;
 
 
@@ -513,7 +517,8 @@
    message on stderr.  */
 
 int
-diff_exec (char *file1, char *file2, char *label1, char *label2, char 
*options, char *out)
+diff_exec (const char *file1, const char *file2, const char *label1,
+    const char *label2, const char *options, const char *out)
 {
     char *args;
 
@@ -550,9 +555,8 @@
     }
 #endif
 
-    args = xmalloc (strlen (options) + 10);
     /* The first word in this string is used only for error reporting. */
-    sprintf (args, "diff %s", options);
+    (void) xasprintf (&args, "diff %s", options);
     call_diff_setup (args);
     if (label1)
        call_diff_arg (label1);
@@ -573,13 +577,11 @@
    that I have seen. */
 
 static void
-RCS_output_diff_options (char *opts, char *rev1, char *rev2, char *workfile)
+RCS_output_diff_options (const char *opts, const char *rev1,
+    const char *rev2, const char *workfile)
 {
     char *tmp;
-
-    tmp = (char *) xmalloc (strlen (opts) + strlen (rev1) + 10);
-
-    sprintf (tmp, "diff%s -r%s", opts, rev1);
+    (void) xasprintf (&tmp, "diff%s -r%s", opts, rev1);
     cvs_output (tmp, 0);
     free (tmp);
 
Index: src/recurse.c
===================================================================
RCS file: /cvs/ccvs/src/recurse.c,v
retrieving revision 1.91
diff -u -u -r1.91 recurse.c
--- src/recurse.c       24 Oct 2003 20:32:09 -0000      1.91
+++ src/recurse.c       25 Oct 2003 02:17:37 -0000
@@ -35,7 +35,7 @@
     int aflag;
     int locktype;
     int dosrcs;
-    char *repository;                  /* Keep track of repository for rtag */
+    const char *repository;            /* Keep track of repository for rtag */
 };
 
 static int do_recursion (struct recursion_frame *frame);
@@ -151,7 +151,8 @@
                  DIRENTPROC direntproc, DIRLEAVEPROC dirleaveproc,
                  void *callerdat, int argc, char **argv, int local,
                  int which, int aflag, int locktype,
-                 char *update_preload, int dosrcs, char *repository_in)
+                 const char *update_preload, int dosrcs,
+                const char *repository_in)
 {
     int i, err = 0;
 #ifdef CLIENT_SUPPORT
@@ -359,9 +360,7 @@
            if (!(which & W_LOCAL))
            {
                /* If doing rtag, we've done a chdir to the repository. */
-               file_to_try = xmalloc( strlen( argv[i] )
-                                      + sizeof( RCSEXT ) + 1 );
-               sprintf (file_to_try, "%s%s", argv[i], RCSEXT);
+               (void) xasprintf (&file_to_try, "%s%s", argv[i], RCSEXT);
            }
            else
                file_to_try = xstrdup (argv[i]);
@@ -381,22 +380,15 @@
                    char *repos;
                    char *reposfile;
 
-                   tmp_update_dir = xmalloc (strlen (update_dir)
-                                             + strlen (dir)
-                                             + 5);
-                   strcpy (tmp_update_dir, update_dir);
-
-                   if (*tmp_update_dir != '\0')
-                       strcat (tmp_update_dir, "/");
-
-                   strcat (tmp_update_dir, dir);
+                   if (*update_dir != '\0')
+                       (int) xasprintf (&tmp_update_dir, "%s/%s", update_dir,
+                           dir);
+                   else
+                       tmp_update_dir = xstrdup (dir);
 
                    /* look for it in the repository. */
                    repos = Name_Repository (dir, tmp_update_dir);
-                   reposfile = xmalloc (strlen (repos)
-                                        + strlen (comp)
-                                        + 5);
-                   sprintf (reposfile, "%s/%s", repos, comp);
+                   (void) xasprintf (&reposfile, "%s/%s", repos, comp);
                    free (repos);
 
                    if (!wrap_name_has (comp, WRAP_TOCVS) && isdir (reposfile))
@@ -404,8 +396,8 @@
                    else
                        addfile (&files_by_dir, dir, comp);
 
-                   free (tmp_update_dir);
                    free (reposfile);
+                   free (tmp_update_dir);
                }
                else
                    addfile (&files_by_dir, dir, comp);
@@ -891,19 +883,15 @@
 {
     struct frame_and_file *frfile = (struct frame_and_file *)closure;
     struct file_info *finfo = frfile->finfo;
+    char *fullname;
     int ret;
 
     finfo->file = p->key;
-    finfo->fullname = xmalloc (strlen (finfo->file)
-                              + strlen (finfo->update_dir)
-                              + 2);
-    finfo->fullname[0] = '\0';
     if (finfo->update_dir[0] != '\0')
-    {
-       strcat (finfo->fullname, finfo->update_dir);
-       strcat (finfo->fullname, "/");
-    }
-    strcat (finfo->fullname, finfo->file);
+       xasprintf (&fullname, "%s/%s", finfo->update_dir, finfo->file);
+    else
+       fullname = xstrdup (finfo->file);
+    finfo->fullname = fullname;
 
     if (frfile->frame->dosrcs && repository)
     {
@@ -918,8 +906,9 @@
        if (finfo->rcs == NULL
            && !(frfile->frame->which & W_LOCAL))
        {
-           error (0, 0, "could not read RCS file for %s", finfo->fullname);
-           free (finfo->fullname);
+           error (0, 0, "could not read RCS file for %s", fullname);
+           free (fullname);
+           finfo->fullname = NULL;
            cvs_flushout ();
            return 0;
        }
@@ -929,7 +918,8 @@
     ret = frfile->frame->fileproc (frfile->frame->callerdat, finfo);
 
     freercsnode(&finfo->rcs);
-    free (finfo->fullname);
+    free (fullname);
+    finfo->fullname = NULL;
 
     /* Allow the user to monitor progress with tail -f.  Doing this once
        per file should be no big deal, but we don't want the performance
@@ -993,21 +983,14 @@
     }
 
     saved_update_dir = update_dir;
-    update_dir = xmalloc (strlen (saved_update_dir)
-                         + strlen (dir)
-                         + 5);
-    strcpy (update_dir, saved_update_dir);
 
     /* set up update_dir - skip dots if not at start */
     if (strcmp (dir, ".") != 0)
     {
-       if (update_dir[0] != '\0')
-       {
-           (void) strcat (update_dir, "/");
-           (void) strcat (update_dir, dir);
-       }
+       if (saved_update_dir[0] != '\0')
+           (void) xasprintf (&update_dir, "%s/%s", saved_update_dir, dir);
        else
-           (void) strcpy (update_dir, dir);
+           update_dir = xstrdup (dir);
 
        /*
         * Here we need a plausible repository name for the sub-directory. We
@@ -1019,15 +1002,14 @@
        if (repository == NULL)
            newrepos = xstrdup ("");
        else
-       {
-           newrepos = xmalloc (strlen (repository) + strlen (dir) + 5);
-           sprintf (newrepos, "%s/%s", repository, dir);
-       }
+           (void) xasprintf (&newrepos, "%s/%s", repository, dir);
     }
     else
     {
-       if (update_dir[0] == '\0')
-           (void) strcpy (update_dir, dir);
+       if (saved_update_dir[0] == '\0')
+           update_dir = xstrdup (dir);
+       else
+           update_dir = xstrdup (saved_update_dir);
 
        if (repository == NULL)
            newrepos = xstrdup ("");
@@ -1050,19 +1032,11 @@
     {
        char *cvsadmdir;
 
-       cvsadmdir = xmalloc (strlen (dir)
-                            + sizeof (CVSADM_REP)
-                            + sizeof (CVSADM_ENT)
-                            + 80);
-
-       strcpy (cvsadmdir, dir);
-       strcat (cvsadmdir, "/");
-       strcat (cvsadmdir, CVSADM);
+       (void) xasprintf (&cvsadmdir, "%s/%s", dir, CVSADM);
        if (isdir (cvsadmdir))
        {
-           strcpy (cvsadmdir, dir);
-           strcat (cvsadmdir, "/");
-           strcat (cvsadmdir, CVSADM_REP);
+           free (cvsadmdir);
+           (void) xasprintf (&cvsadmdir, "%s/%s", dir, CVSADM_REP);
            if (!isfile (cvsadmdir))
            {
                /* Some commands like update may have printed "? foo" but
@@ -1076,9 +1050,8 @@
            /* Likewise for CVS/Entries.  */
            if (dir_return != R_SKIP_ALL)
            {
-               strcpy (cvsadmdir, dir);
-               strcat (cvsadmdir, "/");
-               strcat (cvsadmdir, CVSADM_ENT);
+               free (cvsadmdir);
+               (void) xasprintf (&cvsadmdir, "%s/%s", dir, CVSADM_ENT);
                if (!isfile (cvsadmdir))
                {
                    /* Some commands like update may have printed "? foo" but
@@ -1163,6 +1136,7 @@
     /* only process the dir if the return code was 0 */
     if (dir_return != R_SKIP_ALL)
     {
+       char *rep = NULL;
        /* save our current directory and static vars */
         if (save_cwd (&cwd))
            exit (EXIT_FAILURE);
@@ -1195,20 +1169,18 @@
        if ( repository )
        {
            if ( strcmp ( dir, "." ) == 0 )
-               xframe.repository = xstrdup ( repository );
+               xframe.repository = rep = xstrdup ( repository );
            else
            {
-               xframe.repository = xmalloc ( strlen ( repository )
-                                             + strlen ( dir )
-                                             + 2 );
-               sprintf ( xframe.repository, "%s/%s", repository, dir );
+               (void) xasprintf ( &rep , "%s/%s", repository, dir );
+               xframe.repository = rep;
            }
        }
        else
            xframe.repository = NULL;
        err += do_recursion (&xframe);
-       if ( xframe.repository )
-           free ( xframe.repository );
+       if ( rep )
+           free ( rep );
 
        /* put the `.' back if necessary */
        if (stripped_dot)
@@ -1303,15 +1275,10 @@
            error (1, errno, "could not chdir to %s", p->key);
 
        save_update_dir = update_dir;
-       update_dir = xmalloc (strlen (save_update_dir)
-                                 + strlen (p->key)
-                                 + 5);
-       strcpy (update_dir, save_update_dir);
-
-       if (*update_dir != '\0')
-           (void) strcat (update_dir, "/");
-
-       (void) strcat (update_dir, p->key);
+       if (*save_update_dir != '\0')
+           (void) xasprintf (&update_dir, "%s/%s", save_update_dir, p->key);
+       else
+           update_dir = xstrdup (p->key);
     }
 
     err += do_recursion (frame);
Index: src/release.c
===================================================================
RCS file: /cvs/ccvs/src/release.c,v
retrieving revision 1.53
diff -u -u -r1.53 release.c
--- src/release.c       5 Oct 2003 00:37:16 -0000       1.53
+++ src/release.c       25 Oct 2003 02:17:37 -0000
@@ -113,10 +113,7 @@
      * (ignore-193 in testsuite)).
      */
     /* Construct the update command. */
-    update_cmd = xmalloc (strlen (program_path)
-                         + strlen (current_parsed_root->original)
-                         + 20);
-    sprintf (update_cmd, "%s -n -q -d %s update",
+    (void) xasprintf (&update_cmd, "%s -n -q -d %s update",
              program_path, current_parsed_root->original);
 
 #ifdef CLIENT_SUPPORT
Index: src/remove.c
===================================================================
RCS file: /cvs/ccvs/src/remove.c,v
retrieving revision 1.58
diff -u -u -r1.58 remove.c
--- src/remove.c        29 Aug 2003 16:58:30 -0000      1.58
+++ src/remove.c        25 Oct 2003 02:17:37 -0000
@@ -22,8 +22,8 @@
                                         struct file_info *finfo);
 #endif
 static int remove_fileproc (void *callerdat, struct file_info *finfo);
-static Dtype remove_dirproc (void *callerdat, char *dir,
-                                   char *repos, char *update_dir,
+static Dtype remove_dirproc (void *callerdat, const char *dir,
+                                   const char *repos, const char *update_dir,
                                    List *entries);
 
 static int force;
@@ -114,7 +114,7 @@
        ( remove_fileproc, (FILESDONEPROC) NULL,
          remove_dirproc, (DIRLEAVEPROC) NULL, NULL, argc, argv,
          local, W_LOCAL, 0, CVS_LOCK_READ, (char *) NULL, 1,
-         (char *) NULL );
+         (const char *) NULL );
 
     if (removed_files && !really_quiet)
        error (0, 0, "use `%s commit' to remove %s permanently", program_name,
@@ -193,11 +193,7 @@
         * remove the ,t file for it and scratch it from the
         * entries file.  */
        Scratch_Entry (finfo->entries, finfo->file);
-       fname = xmalloc (strlen (finfo->file)
-                        + sizeof (CVSADM)
-                        + sizeof (CVSEXT_LOG)
-                        + 10);
-       (void) sprintf (fname, "%s/%s%s", CVSADM, finfo->file, CVSEXT_LOG);
+       (void) xasprintf (&fname, "%s/%s%s", CVSADM, finfo->file, CVSEXT_LOG);
        if (unlink_file (fname) < 0
            && !existence_error (errno))
            error (0, errno, "cannot remove %s", CVSEXT_LOG);
@@ -245,9 +241,7 @@
        char *fname;
 
        /* Re-register it with a negative version number.  */
-       fname = xmalloc (strlen (vers->vn_user) + 5);
-       (void) strcpy (fname, "-");
-       (void) strcat (fname, vers->vn_user);
+       (void) xasprintf(&fname, "-%s", vers->vn_user);
        Register (finfo->entries, finfo->file, fname, vers->ts_rcs, 
vers->options,
                  vers->tag, vers->date, vers->ts_conflict);
        if (!quiet)
@@ -270,7 +264,8 @@
  */
 /* ARGSUSED */
 static Dtype
-remove_dirproc (void *callerdat, char *dir, char *repos, char *update_dir, 
List *entries)
+remove_dirproc (void *callerdat, const char *dir, const char *repos,
+    const char *update_dir, List *entries)
 {
     if (!quiet)
        error (0, 0, "Removing %s", update_dir);
Index: src/repos.c
===================================================================
RCS file: /cvs/ccvs/src/repos.c,v
retrieving revision 1.31
diff -u -u -r1.31 repos.c
--- src/repos.c 24 Oct 2003 19:32:19 -0000      1.31
+++ src/repos.c 25 Oct 2003 02:17:37 -0000
@@ -19,10 +19,10 @@
    invoked.  */
 
 char *
-Name_Repository (char *dir, char *update_dir)
+Name_Repository (const char *dir, const char *update_dir)
 {
     FILE *fpin;
-    char *xupdate_dir;
+    const char *xupdate_dir;
     char *repos = NULL;
     size_t repos_allocated = 0;
     char *tmp;
@@ -34,10 +34,7 @@
        xupdate_dir = ".";
 
     if (dir != NULL)
-    {
-       tmp = xmalloc (strlen (dir) + sizeof (CVSADM_REP) + 10);
-       (void) sprintf (tmp, "%s/%s", dir, CVSADM_REP);
-    }
+       (void) xasprintf (&tmp, "%s/%s", dir, CVSADM_REP);
     else
        tmp = xstrdup (CVSADM_REP);
 
@@ -53,10 +50,7 @@
        char *cvsadm;
 
        if (dir != NULL)
-       {
-           cvsadm = xmalloc (strlen (dir) + sizeof (CVSADM) + 10);
-           (void) sprintf (cvsadm, "%s/%s", dir, CVSADM);
-       }
+           (void) xasprintf (&cvsadm, "%s/%s", dir, CVSADM);
        else
            cvsadm = xstrdup (CVSADM);
 
@@ -119,8 +113,8 @@
            error (0, 0, "`..'-relative repositories are not supported.");
            error (1, 0, "invalid source repository");
        }
-       newrepos = xmalloc (strlen (current_parsed_root->directory) + strlen 
(repos) + 2);
-       (void) sprintf (newrepos, "%s/%s", current_parsed_root->directory, 
repos);
+       (void) xasprintf (&newrepos, "%s/%s", current_parsed_root->directory,
+           repos);
        free (repos);
        repos = newrepos;
     }
@@ -134,8 +128,8 @@
  * Return a pointer to the repository name relative to CVSROOT from a
  * possibly fully qualified repository
  */
-char *
-Short_Repository (char *repository)
+const char *
+Short_Repository (const char *repository)
 {
     if (repository == NULL)
        return (NULL);
@@ -145,7 +139,7 @@
     if (strncmp (current_parsed_root->directory, repository,
                 strlen (current_parsed_root->directory)) == 0)
     {
-       char *rep = repository + strlen (current_parsed_root->directory);
+       const char *rep = repository + strlen (current_parsed_root->directory);
        return (*rep == '/') ? rep+1 : rep;
     }
     else
Index: src/root.c
===================================================================
RCS file: /cvs/ccvs/src/root.c,v
retrieving revision 1.74
diff -u -u -r1.74 root.c
--- src/root.c  5 Oct 2003 00:37:16 -0000       1.74
+++ src/root.c  25 Oct 2003 02:17:37 -0000
@@ -24,10 +24,11 @@
 #ifndef DEBUG
 
 char *
-Name_Root (char *dir, char *update_dir)
+Name_Root (const char *dir, const char *update_dir)
 {
     FILE *fpin;
-    char *ret, *xupdate_dir;
+    char *ret;
+    const char *xupdate_dir;
     char *root = NULL;
     size_t root_allocated = 0;
     char *tmp;
@@ -42,10 +43,8 @@
 
     if (dir != NULL)
     {
-       cvsadm = xmalloc (strlen (dir) + sizeof (CVSADM) + 10);
-       (void) sprintf (cvsadm, "%s/%s", dir, CVSADM);
-       tmp = xmalloc (strlen (dir) + sizeof (CVSADM_ROOT) + 10);
-       (void) sprintf (tmp, "%s/%s", dir, CVSADM_ROOT);
+       (void) xasprintf (&cvsadm, "%s/%s", dir, CVSADM);
+       (void) xasprintf (&tmp, "%s/%s", dir, CVSADM_ROOT);
     }
     else
     {
@@ -139,7 +138,7 @@
  * future work.
  */
 void
-Create_Root (char *dir, char *rootdir)
+Create_Root (const char *dir, const char *rootdir)
 {
     FILE *fout;
     char *tmp;
@@ -152,10 +151,7 @@
     if (rootdir != NULL)
     {
         if (dir != NULL)
-       {
-           tmp = xmalloc (strlen (dir) + sizeof (CVSADM_ROOT) + 10);
-           (void) sprintf (tmp, "%s/%s", dir, CVSADM_ROOT);
-       }
+           (void) xasprintf (&tmp, "%s/%s", dir, CVSADM_ROOT);
         else
            tmp = xstrdup (CVSADM_ROOT);
 
@@ -180,7 +176,7 @@
 static int root_allow_size;
 
 void
-root_allow_add (char *arg)
+root_allow_add (const char *arg)
 {
     char *p;
 
@@ -227,7 +223,7 @@
 }
 
 int
-root_allow_ok (char *arg)
+root_allow_ok (const char *arg)
 {
     int i;
 
@@ -729,10 +725,7 @@
 
     /* get the username string */
     username = root->username ? root->username : getcaller();
-    cvsroot_canonical = xmalloc ( strlen(username)
-                               + strlen(hostname) + strlen(port_s)
-                               + strlen(root->directory) + 12);
-    sprintf (cvsroot_canonical, ":pserver:%s@%s:%s%s",
+    (void) xasprintf (&cvsroot_canonical, ":pserver:%s@%s:%s%s",
            username, hostname, port_s, root->directory);
 
     free (hostname);
Index: src/rsh-client.c
===================================================================
RCS file: /cvs/ccvs/src/rsh-client.c,v
retrieving revision 1.6
diff -u -u -r1.6 rsh-client.c
--- src/rsh-client.c    23 Jul 2003 20:42:26 -0000      1.6
+++ src/rsh-client.c    25 Oct 2003 02:17:37 -0000
@@ -141,13 +141,12 @@
        affect most rsh servers at all, and will pacify some buggy
        versions of rsh that grab switches out of the middle of the
        command (they're calling the GNU getopt routines incorrectly).  */
-    command = xmalloc (strlen (cvs_server) + 8);
 
     /* If you are running a very old (Nov 3, 1994, before 1.5)
      * version of the server, you need to make sure that your .bashrc
      * on the server machine does not set CVSROOT to something
      * containing a colon (or better yet, upgrade the server).  */
-    sprintf (command, "%s server", cvs_server);
+    (void) xasprintf (&command, "%s server", cvs_server);
 
     {
         char *argv[10];
Index: src/sanity.sh
===================================================================
RCS file: /cvs/ccvs/src/sanity.sh,v
retrieving revision 1.830
diff -u -u -r1.830 sanity.sh
--- src/sanity.sh       24 Oct 2003 23:03:20 -0000      1.830
+++ src/sanity.sh       25 Oct 2003 02:17:42 -0000
@@ -79,6 +79,7 @@
 
 # required to make this script work properly.
 unset CVSREAD
+unset CVSWRAPPERS
 
 # We want to invoke a predictable set of i18n behaviors, not whatever
 # the user running this script might have set.
Index: src/scramble.c
===================================================================
RCS file: /cvs/ccvs/src/scramble.c,v
retrieving revision 1.17
diff -u -u -r1.17 scramble.c
--- src/scramble.c      23 Jul 2003 20:42:26 -0000      1.17
+++ src/scramble.c      25 Oct 2003 02:17:42 -0000
@@ -84,7 +84,7 @@
 
 /* Return a xmalloc'd, scrambled version of STR. */
 char *
-scramble (char *str)
+scramble (const char *str)
 {
     int i;
     char *s;
@@ -106,7 +106,7 @@
 
 /* Decode the string in place. */
 char *
-descramble (char *str)
+descramble (const char *str)
 {
     char *s;
     int i;
Index: src/server.c
===================================================================
RCS file: /cvs/ccvs/src/server.c,v
retrieving revision 1.328
diff -u -u -r1.328 server.c
--- src/server.c        12 Oct 2003 00:07:43 -0000      1.328
+++ src/server.c        25 Oct 2003 02:17:43 -0000
@@ -315,28 +315,16 @@
 static int
 create_adm_p (char *base_dir, char *dir)
 {
-    char *dir_where_cvsadm_lives, *dir_to_register, *p, *tmp;
+    char *dir_where_cvsadm_lives, *dir_to_register, *p, *tmp = NULL;
     int retval, done;
     FILE *f;
 
     if (strcmp (dir, ".") == 0)
        return 0;                       /* nothing to do */
 
-    /* Allocate some space for our directory-munging string. */
-    p = xmalloc (strlen (dir) + 1);
-    if (p == NULL)
-       return ENOMEM;
-
-    dir_where_cvsadm_lives = xmalloc (strlen (base_dir) + strlen (dir) + 100);
-    if (dir_where_cvsadm_lives == NULL)
-       return ENOMEM;
-
-    /* Allocate some space for the temporary string in which we will
-       construct filenames. */
-    tmp = xmalloc (strlen (base_dir) + strlen (dir) + 100);
-    if (tmp == NULL)
-       return ENOMEM;
+    p = xstrdup (dir);
 
+    (void) xasprintf (&dir_where_cvsadm_lives, "%s/%s", base_dir, p);
 
     /* We make several passes through this loop.  On the first pass,
        we simply create the CVSADM directory in the deepest directory.
@@ -347,24 +335,23 @@
 
     retval = done = 0;
 
-    strcpy (p, dir);
-    strcpy (dir_where_cvsadm_lives, base_dir);
-    strcat (dir_where_cvsadm_lives, "/");
-    strcat (dir_where_cvsadm_lives, p);
     dir_to_register = NULL;
 
     while (1)
     {
+       if (tmp)
+               free (tmp);
        /* Create CVSADM. */
-       (void) sprintf (tmp, "%s/%s", dir_where_cvsadm_lives, CVSADM);
+       (void) xasprintf (&tmp, "%s/%s", dir_where_cvsadm_lives, CVSADM);
        if ((CVS_MKDIR (tmp, 0777) < 0) && (errno != EEXIST))
        {
            retval = errno;
            goto finish;
        }
 
+       free (tmp);
        /* Create CVSADM_REP. */
-       (void) sprintf (tmp, "%s/%s", dir_where_cvsadm_lives, CVSADM_REP);
+       (void) xasprintf (&tmp, "%s/%s", dir_where_cvsadm_lives, CVSADM_REP);
        if (! isfile (tmp))
        {
            /* Use Emptydir as the placeholder until the client sends
@@ -373,19 +360,9 @@
               differently.  */
 
            char *empty;
-           empty = xmalloc (strlen (current_parsed_root->directory)
-                           + sizeof (CVSROOTADM)
-                           + sizeof (CVSNULLREPOS)
-                           + 3);
-           if (! empty)
-           {
-               retval = ENOMEM;
-               goto finish;
-           }
-
            /* Create the directory name. */
-           (void) sprintf (empty, "%s/%s/%s", current_parsed_root->directory,
-                           CVSROOTADM, CVSNULLREPOS);
+           (void) xasprintf (&empty, "%s/%s/%s",
+               current_parsed_root->directory, CVSROOTADM, CVSNULLREPOS);
 
            /* Create the directory if it doesn't exist. */
            if (! isfile (empty))
@@ -429,14 +406,10 @@
 
        /* Create CVSADM_ENT.  We open in append mode because we
           don't want to clobber an existing Entries file.  */
-       (void) sprintf (tmp, "%s/%s", dir_where_cvsadm_lives, CVSADM_ENT);
+       free (tmp);
+       (void) xasprintf (&tmp, "%s/%s", dir_where_cvsadm_lives, CVSADM_ENT);
        f = CVS_FOPEN (tmp, "a");
-       if (f == NULL)
-       {
-           retval = errno;
-           goto finish;
-       }
-       if (fclose (f) == EOF)
+       if (f == NULL || fclose (f) == EOF)
        {
            retval = errno;
            goto finish;
@@ -474,7 +447,8 @@
     }
 
   finish:
-    free (tmp);
+    if (tmp)
+           free (tmp);
     free (dir_where_cvsadm_lives);
     free (p);
     return retval;
@@ -740,15 +714,7 @@
        nothing.  But for rsh, we need to do it now.  */
     parse_config (current_parsed_root->directory);
 
-    path = xmalloc (strlen (current_parsed_root->directory)
-                  + sizeof (CVSROOTADM)
-                  + 2);
-    if (path == NULL)
-    {
-       pending_error = ENOMEM;
-       return;
-    }
-    (void) sprintf (path, "%s/%s", current_parsed_root->directory, CVSROOTADM);
+    (void) xasprintf (&path, "%s/%s", current_parsed_root->directory, 
CVSROOTADM);
     if (!isaccessible (path, R_OK | X_OK))
     {
        int save_errno = errno;
@@ -759,13 +725,7 @@
     free (path);
 
 #ifdef HAVE_PUTENV
-    env = xmalloc (strlen (CVSROOT_ENV) + strlen 
(current_parsed_root->directory) + 2);
-    if (env == NULL)
-    {
-       pending_error = ENOMEM;
-       return;
-    }
-    (void) sprintf (env, "%s=%s", CVSROOT_ENV, current_parsed_root->directory);
+    (void) xasprintf (&env, "%s=%s", CVSROOT_ENV, 
current_parsed_root->directory);
     (void) putenv (env);
     /* do not free env, as putenv has control of it */
 #endif
@@ -954,17 +914,7 @@
     if (dir_name != NULL)
        free (dir_name);
 
-    dir_name = xmalloc (strlen (server_temp_dir) + dir_len + 40);
-    if (dir_name == NULL)
-    {
-       pending_error = ENOMEM;
-       return;
-    }
-
-    strcpy (dir_name, server_temp_dir);
-    strcat (dir_name, "/");
-    strcat (dir_name, dir);
-
+    (void) xasprintf (&dir_name, "%s/%s", server_temp_dir, dir);
     status = mkdir_p (dir_name);
     if (status != 0
        && status != EEXIST)
@@ -1889,18 +1839,8 @@
        pending_error = ENOMEM;
        return;
     }
-    new->dir = xmalloc (strlen (dir_name) + 1);
-    new->filename = xmalloc (strlen (arg) + 1);
-    if (new->dir == NULL || new->filename == NULL)
-    {
-       pending_error = ENOMEM;
-       if (new->dir != NULL)
-           free (new->dir);
-       free (new);
-       return;
-    }
-    strcpy (new->dir, dir_name);
-    strcpy (new->filename, arg);
+    new->dir = xstrdup (dir_name);
+    new->filename = xstrdup (arg);
 
     status = buf_read_line (buf_from_net, &data, (int *) NULL);
     if (status != 0)
@@ -2399,18 +2339,11 @@
         int num_red = 0;
         size_t linebuf_len = 0;
         char *fname;
-        size_t flen;
         FILE *fp;
         int found_it = 0;
 
         /* else */
-        flen = strlen (current_parsed_root->directory)
-               + strlen (CVSROOTADM)
-               + strlen (CVSROOTADM_READERS)
-               + 3;
-
-        fname = xmalloc (flen);
-        (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory,
+        (void) xasprintf (&fname, "%s/%s/%s", current_parsed_root->directory,
                        CVSROOTADM, CVSROOTADM_READERS);
 
         fp = fopen (fname, "r");
@@ -2456,13 +2389,7 @@
 
         /* Now check the writers file.  */
 
-        flen = strlen (current_parsed_root->directory)
-               + strlen (CVSROOTADM)
-               + strlen (CVSROOTADM_WRITERS)
-               + 3;
-
-        fname = xmalloc (flen);
-        (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory,
+        (void) xasprintf (&fname, "%s/%s/%s", current_parsed_root->directory,
                        CVSROOTADM, CVSROOTADM_WRITERS);
 
         fp = fopen (fname, "r");
@@ -3271,10 +3198,10 @@
 /* This variable commented in server.h.  */
 char *server_dir = NULL;
 
-static void output_dir (char *, char *);
+static void output_dir (const char *, const char *);
 
 static void
-output_dir (char *update_dir, char *repository)
+output_dir (const char *update_dir, const char *repository)
 {
     if (server_dir != NULL)
     {
@@ -3309,7 +3236,9 @@
 static int kill_scratched_file;
 
 void
-server_register (char *name, char *version, char *timestamp, char *options, 
char *tag, char *date, char *conflict)
+server_register (const char *name, const char *version, const char *timestamp,
+    const char *options, const char *tag, const char *date,
+    const char *conflict)
 {
     int len;
 
@@ -3371,7 +3300,7 @@
 }
 
 void
-server_scratch (char *fname)
+server_scratch (const char *fname)
 {
     /*
      * I have reports of Scratch_Entry and Register both happening, in
@@ -3432,7 +3361,8 @@
 }
 
 static void
-checked_in_response (char *file, char *update_dir, char *repository)
+checked_in_response (const char *file, const char *update_dir,
+    const char *repository)
 {
     if (supported_response ("Mode"))
     {
@@ -3464,7 +3394,8 @@
 }
 
 void
-server_checked_in (char *file, char *update_dir, char *repository)
+server_checked_in (const char *file, const char *update_dir,
+    const char *repository)
 {
     if (noexec)
        return;
@@ -3489,7 +3420,7 @@
 }
 
 void
-server_update_entries (char *file, char *update_dir, char *repository, enum 
server_updated_arg4 updated)
+server_update_entries (const char *file, const char *update_dir, const char 
*repository, enum server_updated_arg4 updated)
 {
     if (noexec)
        return;
@@ -3784,7 +3715,8 @@
 }
 
 void
-server_copy_file (char *file, char *update_dir, char *repository, char 
*newfile)
+server_copy_file (const char *file, const char *update_dir,
+    const char *repository, const char *newfile)
 {
     /* At least for now, our practice is to have the server enforce
        noexec for the repository and the client enforce it for the
@@ -4137,7 +4069,7 @@
 }
 
 void
-server_set_entstat (char *update_dir, char *repository)
+server_set_entstat (const char *update_dir, const char *repository)
 {
     static int set_static_supported = -1;
     if (set_static_supported == -1)
@@ -4151,7 +4083,7 @@
 }
 
 void
-server_clear_entstat (char *update_dir, char *repository)
+server_clear_entstat (const char *update_dir, const char *repository)
 {
     static int clear_static_supported = -1;
     if (clear_static_supported == -1)
@@ -4168,7 +4100,7 @@
 }
 
 void
-server_set_sticky (char *update_dir, char *repository, char *tag, char *date, 
int nonbranch)
+server_set_sticky (const char *update_dir, const char *repository, const char 
*tag, const char *date, int nonbranch)
 {
     static int set_sticky_supported = -1;
 
@@ -4212,12 +4144,12 @@
 
 struct template_proc_data
 {
-    char *update_dir;
-    char *repository;
+    const char *update_dir;
+    const char *repository;
 };
 
 static int
-template_proc(char *repository, char *template, void *closure)
+template_proc(const char *repository, const char *template, void *closure)
 {
     FILE *fp;
     char buf[1024];
@@ -4263,7 +4195,7 @@
 }
 
 void
-server_clear_template (char *update_dir, char *repository)
+server_clear_template (const char *update_dir, const char *repository)
 {
     assert (update_dir != NULL);
 
@@ -4293,7 +4225,7 @@
 }
 
 void
-server_template (char *update_dir, char *repository)
+server_template (const char *update_dir, const char *repository)
 {
     struct template_proc_data data;
     data.update_dir = update_dir;
@@ -4370,7 +4302,9 @@
 }
 
 static int
-expand_proc (int argc, char **argv, char *where, char *mwhere, char *mfile, 
int shorten, int local_specified, char *omodule, char *msg)
+expand_proc (int argc, char **argv, const char *where,
+    const char *mwhere, const char *mfile, int shorten, int local_specified,
+    const char *omodule, const char *msg)
 {
     int i;
     char *dir = argv[0];
@@ -4445,7 +4379,7 @@
        err += do_module (db, argument_vector[i],
                          CHECKOUT, "Updating", expand_proc,
                          NULL, 0, 0, 0, 0,
-                         (char *) NULL);
+                         (const char *) NULL);
     close_module (db);
     {
        /* argument_vector[0] is a dummy argument, we don't mess with it.  */
@@ -6156,7 +6090,7 @@
    output zero bytes.  */
 
 void
-cvs_output_binary (char *str, size_t len)
+cvs_output_binary (const char *str, size_t len)
 {
 #ifdef SERVER_SUPPORT
     if (error_use_protocol || server_active)
@@ -6370,7 +6304,7 @@
    Note that there is no way to output either \0 or \n as part of TEXT.  */
 
 void
-cvs_output_tagged (char *tag, char *text)
+cvs_output_tagged (const char *tag, const char *text)
 {
     if (text != NULL && strchr (text, '\n') != NULL)
        /* Uh oh.  The protocol has no way to cope with this.  For now
Index: src/server.h
===================================================================
RCS file: /cvs/ccvs/src/server.h,v
retrieving revision 1.32
diff -u -u -r1.32 server.h
--- src/server.h        24 Oct 2003 15:09:44 -0000      1.32
+++ src/server.h        25 Oct 2003 02:17:43 -0000
@@ -44,8 +44,10 @@
 void server_pathname_check (char *);
 
 /* We have a new Entries line for a file.  TAG or DATE can be NULL.  */
-void server_register (char *name, char *version, char *timestamp,
-                      char *options, char *tag, char *date, char *conflict);
+extern void server_register (const char *name, const char *version,
+                            const char *timestamp, const char *options,
+                            const char *tag, const char *date,
+                            const char *conflict);
 
 /* Set the modification time of the next file sent.  This must be
    followed by a call to server_updated on the same file.  */
@@ -55,7 +57,7 @@
  * We want to nuke the Entries line for a file, and (unless
  * server_scratch_entry_only is subsequently called) the file itself.
  */
-void server_scratch (char *name);
+void server_scratch (const char *name);
 
 /*
  * The file which just had server_scratch called on it needs to have only
@@ -68,10 +70,11 @@
  * filename, with no directory).  REPOSITORY is the directory for the
  * repository.
  */
-void server_checked_in (char *file, char *update_dir, char *repository);
+void server_checked_in (const char *file, const char *update_dir,
+                       const char *repository);
 
-void server_copy_file (char *file, char *update_dir, char *repository,
-                       char *newfile);
+void server_copy_file (const char *file, const char *update_dir,
+                      const char *repository, const char *newfile);
 
 /* Send the appropriate responses for a file described by FINFO and
    VERS.  This is called after server_register or server_scratch.  In
@@ -104,22 +107,23 @@
 int server_use_rcs_diff (void);
 
 /* Set the Entries.Static flag.  */
-void server_set_entstat (char *update_dir, char *repository);
+void server_set_entstat (const char *update_dir, const char *repository);
 /* Clear it.  */
-void server_clear_entstat (char *update_dir, char *repository);
+void server_clear_entstat (const char *update_dir, const char *repository);
 
 /* Set or clear a per-directory sticky tag or date.  */
-void server_set_sticky (char *update_dir, char *repository,
-                        char *tag, char *date, int nonbranch);
+void server_set_sticky (const char *update_dir, const char *repository,
+                       const char *tag, const char *date, int nonbranch);
 
 /* Send Clear-template response.  */
-void server_clear_template (char *update_dir, char *repository);
+void server_clear_template (const char *update_dir, const char *repository);
 
 /* Send Template response.  */
-void server_template (char *update_dir, char *repository);
+void server_template (const char *update_dir, const char *repository);
 
-void server_update_entries (char *file, char *update_dir, char *repository,
-                            enum server_updated_arg4 updated);
+void server_update_entries (const char *file, const char *update_dir,
+                           const char *repository,
+                           enum server_updated_arg4 updated);
 
 /* Pointer to a malloc'd string which is the directory which
    the server should prepend to the pathnames which it sends
@@ -178,5 +182,6 @@
 extern struct request requests[];
 
 /* Gzip library, see zlib.c.  */
-int gunzip_and_write (int, char *, unsigned char *, size_t);
-int read_and_gzip (int, char *, unsigned char **, size_t *, size_t *, int);
+int gunzip_and_write (int, const char *, unsigned char *, size_t);
+int read_and_gzip (int, const char *, unsigned char **, size_t *,
+                  size_t *, int);
Index: src/status.c
===================================================================
RCS file: /cvs/ccvs/src/status.c,v
retrieving revision 1.57
diff -u -u -r1.57 status.c
--- src/status.c        23 Jul 2003 20:42:26 -0000      1.57
+++ src/status.c        25 Oct 2003 02:17:43 -0000
@@ -10,9 +10,9 @@
 
 #include "cvs.h"
 
-static Dtype status_dirproc (void *callerdat, char *dir,
-                                   char *repos, char *update_dir,
-                                   List *entries);
+static Dtype status_dirproc (void *callerdat, const char *dir,
+                            const char *repos, const char *update_dir,
+                            List *entries);
 static int status_fileproc (void *callerdat, struct file_info *finfo);
 static int tag_list_proc (Node * p, void *closure);
 
@@ -191,8 +191,8 @@
     else
     {
        char *buf;
-       buf = xmalloc (strlen (finfo->file) + strlen (sstat) + 80);
-       sprintf (buf, "File: %-17s\tStatus: %s\n\n", finfo->file, sstat);
+       (void) xasprintf (&buf, "File: %-17s\tStatus: %s\n\n", finfo->file,
+           sstat);
        cvs_output (buf, 0);
        free (buf);
     }
@@ -320,7 +320,8 @@
  */
 /* ARGSUSED */
 static Dtype
-status_dirproc (void *callerdat, char *dir, char *repos, char *update_dir, 
List *entries)
+status_dirproc (void *callerdat, const char *dir, const char *repos,
+    const char *update_dir, List *entries)
 {
     if (!quiet)
        error (0, 0, "Examining %s", update_dir);
@@ -339,9 +340,7 @@
     if (RCS_nodeisbranch (xrcsnode, p->key))
        branch = RCS_whatbranch(xrcsnode, p->key) ;
 
-    buf = xmalloc (80 + strlen (p->key)
-                  + (branch ? strlen (branch) : strlen (p->data)));
-    sprintf (buf, "\t%-25s\t(%s: %s)\n", p->key,
+    (void) xasprintf (&buf, "\t%-25s\t(%s: %s)\n", p->key,
             branch ? "branch" : "revision",
             branch ? branch : p->data);
     cvs_output (buf, 0);
Index: src/subr.c
===================================================================
RCS file: /cvs/ccvs/src/subr.c,v
retrieving revision 1.93
diff -u -u -r1.93 subr.c
--- src/subr.c  8 Oct 2003 15:30:25 -0000       1.93
+++ src/subr.c  25 Oct 2003 02:17:43 -0000
@@ -10,6 +10,7 @@
 
 #include "cvs.h"
 #include "getline.h"
+#include <stdarg.h>
 
 #if !defined HAVE_NANOSLEEP && !defined HAVE_USLEEP && defined HAVE_SELECT
   /* use select as a workaround */
@@ -68,6 +69,21 @@
     return (cp);
 }
 
+int
+xasprintf(char **buf, const char *fmt, ...)
+{
+    int len;
+    va_list ap;
+
+    va_start(ap, fmt);
+    len = vasprintf(buf, fmt, ap);
+    va_end(ap);
+
+    if (len == -1)
+       error(1, 0, "out of memory: xasprintf(..., \"%s\", ...) failed", fmt);
+    return len;
+}
+
 /* Two constants which tune expand_string.  Having MIN_INCR as large
    as 1024 might waste a bit of memory, but it shouldn't be too bad
    (CVS used to allocate arrays of, say, 3000, PATH_MAX (8192, often),
@@ -167,9 +183,9 @@
    particularly for the client.c caller.  The server.c caller might
    want something different, so be careful.  */
 int
-pathname_levels (char *path)
+pathname_levels (const char *path)
 {
-    char *p;
+    const char *p;
     char *q;
     int level;
     int max_level;
@@ -221,9 +237,10 @@
    (*ARGV)[0], (*ARGV)[1], ...  Use free_names() to return the memory
    allocated here back to the free pool.  */
 void
-line2argv (int *pargc, char ***argv, char *line, char *sepchars)
+line2argv (int *pargc, char ***argv, const char *line, const char *sepchars)
 {
     char *cp;
+    char *sline = xstrdup(line);
     /* Could make a case for size_t or some other unsigned type, but
        we'll stick with int to avoid signed/unsigned warnings when
        comparing with *pargc.  */
@@ -234,7 +251,7 @@
     *argv = (char **) xmalloc (argv_allocated * sizeof (**argv));
 
     *pargc = 0;
-    for (cp = strtok (line, sepchars); cp; cp = strtok ((char *) NULL, 
sepchars))
+    for (cp = strtok (sline, sepchars); cp; cp = strtok ((char *) NULL, 
sepchars))
     {
        if (*pargc == argv_allocated)
        {
@@ -244,6 +261,7 @@
        (*argv)[*pargc] = xstrdup (cp);
        (*pargc)++;
     }
+    free (sline);
 }
 
 /*
@@ -495,9 +513,10 @@
  *  nonsense about non-empty log fields can be dropped.
  */
 char *
-make_message_rcsvalid (char *message)
+make_message_rcsvalid (const char *message)
 {
-    char *dst, *dp, *mp;
+    char *dst, *dp;
+    const char *mp;
 
     if (message == NULL) message = "";
 
@@ -766,16 +785,11 @@
 
     if (suffix == NULL)
     {
-        backup_name = xmalloc (sizeof (BAKPREFIX) + strlen (filename) + 1);
-        sprintf (backup_name, "%s%s", BAKPREFIX, filename);
+        (void) xasprintf (&backup_name, "%s%s", BAKPREFIX, filename);
     }
     else
     {
-        backup_name = xmalloc (sizeof (BAKPREFIX)
-                               + strlen (filename)
-                               + strlen (suffix)
-                               + 2);  /* one for dot, one for trailing '\0' */
-        sprintf (backup_name, "%s%s.%s", BAKPREFIX, filename, suffix);
+        (void) xasprintf (&backup_name, "%s%s.%s", BAKPREFIX, filename, 
suffix);
     }
 
     if (isfile (filename))
@@ -951,10 +965,7 @@
        found_name is the same length as fname, which is true as
        long as the above code is just ignoring case and not other
        aspects of filename syntax.  */
-    retval = xmalloc (strlen (dir)
-                     + strlen (found_name)
-                     + 2);
-    sprintf (retval, "%s/%s", dir, found_name);
+    (void) xasprintf (&retval, "%s/%s", dir, found_name);
 
     return retval;
 }
@@ -986,6 +997,97 @@
     }
 }
 
+void
+handle_mfile (char *repository, char *where, const char *mfile, int *argc,
+    char ***argv, char **myargv)
+{
+    /* The mfile variable can have one or more path elements.  If
+       it has multiple elements, we want to tack those onto both
+       repository and where.  The last element may refer to either
+       a file or directory.  Here's what to do:
+
+       it refers to a directory
+        -> simply tack it on to where and repository
+       it refers to a file
+        -> munge argv to contain `basename mfile` */
+
+    char *cp;
+    char *path;
+
+
+    /* Paranoia check. */
+
+    if (mfile[strlen (mfile) - 1] == '/')
+    {
+       error (0, 0, "trailing slash on mfile (%s)!", mfile);
+    }
+
+
+    /* Does mfile have multiple path elements? */
+
+    /* if the portion of the module is a path, put the dir part on repos */
+    if ((cp = strrchr (mfile, '/')) != NULL)
+    {
+       *cp = '\0';
+       (void) strcat (repository, "/");
+       (void) strcat (repository, mfile);
+       (void) strcat (where, "/");
+       (void) strcat (where, mfile);
+       mfile = cp + 1;
+    }
+    
+
+    /* Now mfile is a single path element. */
+
+    (void) xasprintf (&path, "%s/%s", repository, mfile);
+    if (isdir (path))
+    {
+       /* It's a directory, so tack it on to repository and
+          where, as we did above. */
+
+       (void) strcat (repository, "/");
+       (void) strcat (repository, mfile);
+       (void) strcat (where, "/");
+       (void) strcat (where, mfile);
+    }
+    else
+    {
+       /* It's a file, which means we have to screw around with
+          argv. */
+       myargv[0] = (*argv)[0];
+       myargv[1] = (char *)mfile;
+       *argc = 2;
+       *argv = myargv;
+    }
+    free (path);
+}
+
+int
+get_repository(char **repository, char **where, const char *mfile,
+    int *argc, char ***argv, char **myargv)
+{
+    size_t mlen = mfile ? strlen (mfile) + 1 : 0;
+    size_t alen = strlen ((*argv)[0]);
+    size_t dlen = strlen (current_parsed_root->directory);
+    *repository = xmalloc (dlen + alen + mlen + 2);
+    (void) sprintf (*repository, "%s/%s", current_parsed_root->directory,
+       (*argv)[0]);
+    *where = xmalloc (alen + mlen + 1);
+    (void) strcpy (*where, (*argv)[0]);
+
+    /* if mfile isn't null, we need to set up to do only part of the module */
+    if (mfile != NULL)
+       handle_mfile(*repository, *where, mfile, argc, argv, myargv);
+
+    /* cd to the starting repository */
+    if ( CVS_CHDIR (*repository) < 0)
+    {
+       error (0, errno, "cannot chdir to %s", repository);
+       free (*repository);
+       return 0;
+    }
+    return 1;
+}
 
 
 /* vim:tabstop=8:shiftwidth=4
Index: src/tag.c
===================================================================
RCS file: /cvs/ccvs/src/tag.c,v
retrieving revision 1.108
diff -u -u -r1.108 tag.c
--- src/tag.c   5 Oct 2003 00:37:16 -0000       1.108
+++ src/tag.c   25 Oct 2003 02:17:43 -0000
@@ -15,20 +15,21 @@
 #include "cvs.h"
 #include "savecwd.h"
 
-static int rtag_proc (int argc, char **argv, char *xwhere,
-                     char *mwhere, char *mfile, int shorten,
-                     int local_specified, char *mname, char *msg);
+static int rtag_proc (int argc, char **argv, const char *xwhere,
+                     const char *mwhere, const char *mfile, int shorten,
+                     int local_specified, const char *mname, const char *msg);
 static int check_fileproc (void *callerdat, struct file_info *finfo);
 static int check_filesdoneproc (void *callerdat, int err,
-                                      char *repos, char *update_dir,
-                                      List *entries);
-static int pretag_proc ( char *repository, char *filter, void *closure );
+                               const char *repos, const char *update_dir,
+                               List *entries);
+static int pretag_proc (const char *repository, const char *filter,
+                       void *closure );
 static void masterlist_delproc (Node *p);
 static void tag_delproc (Node *p);
 static int pretag_list_proc (Node *p, void *closure);
 
-static Dtype tag_dirproc (void *callerdat, char *dir,
-                                char *repos, char *update_dir,
+static Dtype tag_dirproc (void *callerdat, const char *dir,
+                                const char *repos, const char *update_dir,
                                 List *entries);
 static int rtag_fileproc (void *callerdat, struct file_info *finfo);
 static int rtag_delete (RCSNode *rcsfile);
@@ -278,7 +279,9 @@
  */
 /* ARGSUSED */
 static int
-rtag_proc (int argc, char **argv, char *xwhere, char *mwhere, char *mfile, int 
shorten, int local_specified, char *mname, char *msg)
+rtag_proc (int argc, char **argv, const char *xwhere, const char *mwhere,
+    const char *mfile, int shorten, int local_specified, const char *mname,
+    const char *msg)
 {
     /* Begin section which is identical to patch_proc--should this
        be abstracted out somehow?  */
@@ -306,58 +309,9 @@
 
     if (is_rtag)
     {
-       repository = xmalloc (strlen (current_parsed_root->directory) + strlen 
(argv[0])
-                             + (mfile == NULL ? 0 : strlen (mfile) + 1) + 2);
-       (void) sprintf (repository, "%s/%s", current_parsed_root->directory, 
argv[0]);
-       where = xmalloc (strlen (argv[0]) + (mfile == NULL ? 0 : strlen (mfile) 
+ 1)
-                        + 1);
-       (void) strcpy (where, argv[0]);
-
-       /* if mfile isn't null, we need to set up to do only part of the module 
*/
-       if (mfile != NULL)
-       {
-           char *cp;
-           char *path;
-
-           /* if the portion of the module is a path, put the dir part on 
repos */
-           if ((cp = strrchr (mfile, '/')) != NULL)
-           {
-               *cp = '\0';
-               (void) strcat (repository, "/");
-               (void) strcat (repository, mfile);
-               (void) strcat (where, "/");
-               (void) strcat (where, mfile);
-               mfile = cp + 1;
-           }
-
-           /* take care of the rest */
-           path = xmalloc (strlen (repository) + strlen (mfile) + 5);
-           (void) sprintf (path, "%s/%s", repository, mfile);
-           if (isdir (path))
-           {
-               /* directory means repository gets the dir tacked on */
-               (void) strcpy (repository, path);
-               (void) strcat (where, "/");
-               (void) strcat (where, mfile);
-           }
-           else
-           {
-               myargv[0] = argv[0];
-               myargv[1] = mfile;
-               argc = 2;
-               argv = myargv;
-           }
-           free (path);
-       }
-
-       /* cd to the starting repository */
-       if ( CVS_CHDIR (repository) < 0)
-       {
-           error (0, errno, "cannot chdir to %s", repository);
-           free (repository);
-           return (1);
-       }
-       /* End section which is identical to patch_proc.  */
+       if (get_repository(&repository, &where, mfile, &argc, &argv, myargv)
+           == 0)
+           return -1;
 
        if (delete_flag || attic_too || (force_tag_match && numtag))
            which = W_REPOS | W_ATTIC;
@@ -416,7 +370,7 @@
 static int
 check_fileproc (void *callerdat, struct file_info *finfo)
 {
-    char *xdir;
+    const char *xdir;
     Node *p;
     Vers_TS *vers;
 
@@ -548,7 +502,8 @@
 };
 
 static int
-check_filesdoneproc (void *callerdat, int err, char *repos, char *update_dir, 
List *entries)
+check_filesdoneproc (void *callerdat, int err, const char *repos,
+    const char *update_dir, List *entries)
 {
     int n;
     Node *p;
@@ -581,7 +536,7 @@
 }
 
 static int
-pretag_proc(char *repository, char *filter, void *closure)
+pretag_proc(const char *repository, const char *filter, void *closure)
 {
     struct pretag_proc_data *ppd = (struct pretag_proc_data *)closure;
     if (filter[0] == '/')
@@ -1088,7 +1043,8 @@
  */
 /* ARGSUSED */
 static Dtype
-tag_dirproc (void *callerdat, char *dir, char *repos, char *update_dir, List 
*entries)
+tag_dirproc (void *callerdat, const char *dir, const char *repos,
+    const char *update_dir, List *entries)
 {
 
     if (ignore_directory (update_dir))
@@ -1113,7 +1069,7 @@
    if carefully done), and/or be harder to implement correctly.  */
 
 struct val_args {
-    char *name;
+    const char *name;
     int found;
 };
 
@@ -1141,10 +1097,12 @@
     return 0;
 }
 
-static Dtype val_direntproc (void *, char *, char *, char *, List *);
+static Dtype val_direntproc (void *, const char *, const char *,
+    const char *, List *);
 
 static Dtype
-val_direntproc (void *callerdat, char *dir, char *repository, char 
*update_dir, List *entries)
+val_direntproc (void *callerdat, const char *dir, const char *repository,
+    const char *update_dir, List *entries)
 {
     /* This is not quite right--it doesn't get right the case of "cvs
        update -d -r foobar" where foobar is a tag which exists only in
@@ -1168,7 +1126,8 @@
    tag is found in CVSROOTADM_VALTAGS, but there is not (yet) any
    local directory.  */
 void
-tag_check_valid (char *name, int argc, char **argv, int local, int aflag, char 
*repository)
+tag_check_valid (const char *name, int argc, char **argv, int local, int aflag,
+    const char *repository)
 {
     DBM *db;
     char *valtags_filename;
@@ -1194,7 +1153,7 @@
     /* Numeric tags require only a syntactic check.  */
     if (isdigit ((unsigned char) name[0]))
     {
-       char *p;
+       const char *p;
        for (p = name; *p != '\0'; ++p)
        {
            if (!(isdigit ((unsigned char) *p) || *p == '.'))
@@ -1214,14 +1173,11 @@
        If two processes try to write val-tags at the same time, it would
        seem like we are in trouble.  */
 
-    mytag.dptr = name;
+    mytag.dptr = (char *)name;
     mytag.dsize = strlen (name);
 
-    valtags_filename = xmalloc (strlen (current_parsed_root->directory)
-                               + sizeof CVSROOTADM
-                               + sizeof CVSROOTADM_VALTAGS + 3);
-    sprintf (valtags_filename, "%s/%s/%s", current_parsed_root->directory,
-                                          CVSROOTADM, CVSROOTADM_VALTAGS);
+    (void) xasprintf (&valtags_filename, "%s/%s/%s",
+       current_parsed_root->directory, CVSROOTADM, CVSROOTADM_VALTAGS);
     db = dbm_open (valtags_filename, O_RDWR, 0666);
     if (db == NULL)
     {
@@ -1338,7 +1294,8 @@
  */
 
 void
-tag_check_valid_join (char *join_tag, int argc, char **argv, int local, int 
aflag, char *repository)
+tag_check_valid_join (const char *join_tag, int argc, char **argv, int local,
+    int aflag, const char *repository)
 {
     char *c, *s;
 
Index: src/update.c
===================================================================
RCS file: /cvs/ccvs/src/update.c,v
retrieving revision 1.224
diff -u -u -r1.224 update.c
--- src/update.c        24 Oct 2003 23:03:20 -0000      1.224
+++ src/update.c        25 Oct 2003 02:17:44 -0000
@@ -59,16 +59,17 @@
 #endif
 static int merge_file (struct file_info *finfo, Vers_TS *vers);
 static int scratch_file (struct file_info *finfo, Vers_TS *vers);
-static Dtype update_dirent_proc (void *callerdat, char *dir,
-                                       char *repository, char *update_dir,
-                                       List *entries);
-static int update_dirleave_proc (void *callerdat, char *dir,
-                                       int err, char *update_dir,
-                                       List *entries);
+static Dtype update_dirent_proc (void *callerdat, const char *dir,
+                                const char *repository, const char *update_dir,
+                                List *entries);
+static int update_dirleave_proc (void *callerdat, const char *dir,
+                                int err, const char *update_dir,
+                                List *entries);
 static int update_fileproc (void *callerdat, struct file_info *);
 static int update_filesdone_proc (void *callerdat, int err,
-                                        char *repository, char *update_dir,
-                                        List *entries);
+                                 const char *repository,
+                                 const char *update_dir,
+                                 List *entries);
 #ifdef PRESERVE_PERMISSIONS_SUPPORT
 static int get_linkinfo_proc( void *_callerdat, struct _finfo * );
 #endif
@@ -193,7 +194,7 @@
                force_tag_match = 0;
                break;
            case 'r':
-               tag = optarg;
+               tag = xstrdup (optarg);
                break;
            case 'D':
                date = Make_Date (optarg);
@@ -209,9 +210,9 @@
                if (join_rev2)
                    error (1, 0, "only two -j options can be specified");
                if (join_rev1)
-                   join_rev2 = optarg;
+                   join_rev2 = xstrdup (optarg);
                else
-                   join_rev1 = optarg;
+                   join_rev1 = xstrdup (optarg);
                break;
            case 'u':
 #ifdef SERVER_SUPPORT
@@ -419,8 +420,10 @@
                      (char *) NULL );
 
     /* free the space Make_Date allocated if necessary */
-    if (date != NULL)
+    if (date != NULL) {
        free (date);
+       date = NULL;
+    }
 
     return (err);
 }
@@ -434,18 +437,30 @@
  * to determine this value.
  */
 int
-do_update (int argc, char **argv, char *xoptions, char *xtag, char *xdate,
-           int xforce, int local, int xbuild, int xaflag, int xprune,
-           int xpipeout, int which, char *xjoin_rev1, char *xjoin_rev2,
-           char *preload_update_dir, int xdotemplate, char *repository)
+do_update (int argc, char **argv, const char *xoptions, const char *xtag,
+    const char *xdate, int xforce, int local, int xbuild, int xaflag,
+    int xprune, int xpipeout, int which, const char *xjoin_rev1,
+    const char *xjoin_rev2, const char *preload_update_dir, int xdotemplate,
+    const char *repository)
 {
     int err = 0;
     char *cp;
 
     /* fill in the statics */
-    options = xoptions;
-    tag = xtag;
-    date = xdate;
+    cp = xstrdup (xoptions);
+    if (options)
+       free (options);
+    options = cp;
+
+    cp = xstrdup (xtag);
+    if (tag)
+       free (tag);
+    tag = cp;
+
+    cp = xstrdup (xdate);
+    if (date)
+       free (date);
+    date = cp;
     force_tag_match = xforce;
     update_build_dirs = xbuild;
     aflag = xaflag;
@@ -454,8 +469,16 @@
     dotemplate = xdotemplate;
 
     /* setup the join support */
-    join_rev1 = xjoin_rev1;
-    join_rev2 = xjoin_rev2;
+    cp = xstrdup (xjoin_rev1);
+    if (join_rev1)
+       free (join_rev1);
+    join_rev1 = cp;
+
+    cp = xstrdup (xjoin_rev2);
+    if (join_rev2)
+       free (join_rev2);
+    join_rev2 = cp;
+
     if (join_rev1 && (cp = strchr (join_rev1, ':')) != NULL)
     {
        *cp++ = '\0';
@@ -463,6 +486,7 @@
     }
     else
        date_rev1 = (char *) NULL;
+
     if (join_rev2 && (cp = strchr (join_rev2, ':')) != NULL)
     {
        *cp++ = '\0';
@@ -532,9 +556,7 @@
     struct hardlink_info *hlinfo;
 
     /* Get the full pathname of the current file. */
-    fullpath = xmalloc (strlen(working_dir) +
-                       strlen(finfo->fullname) + 2);
-    sprintf (fullpath, "%s/%s", working_dir, finfo->fullname);
+    (void) xasprintf (&fullpath, "%s/%s", working_dir, finfo->fullname);
 
     /* To permit recursing into subdirectories, files
        are keyed on the full pathname and not on the basename. */
@@ -779,33 +801,30 @@
     return (retval);
 }
 
-static void update_ignproc (char *, char *);
+static void update_ignproc (const char *, const char *);
 
 static void
-update_ignproc (char *file, char *dir)
+update_ignproc (const char *file, const char *dir)
 {
     struct file_info finfo;
+    char *fullname;
 
     memset (&finfo, 0, sizeof (finfo));
     finfo.file = file;
     finfo.update_dir = dir;
     if (dir[0] == '\0')
-       finfo.fullname = xstrdup (file);
+       fullname = xstrdup (file);
     else
-    {
-       finfo.fullname = xmalloc (strlen (file) + strlen (dir) + 10);
-       strcpy (finfo.fullname, dir);
-       strcat (finfo.fullname, "/");
-       strcat (finfo.fullname, file);
-    }
-
+       (void) xasprintf (&fullname, "%s/%s", dir, file);
+    finfo.fullname = fullname;
     write_letter (&finfo, '?');
-    free (finfo.fullname);
+    free (fullname);
 }
 
 /* ARGSUSED */
 static int
-update_filesdone_proc (void *callerdat, int err, char *repository, char 
*update_dir, List *entries)
+update_filesdone_proc (void *callerdat, int err, const char *repository,
+    const char *update_dir, List *entries)
 {
     if (nonbranch < 0) nonbranch = 0;
     if (rewrite_tag)
@@ -853,7 +872,8 @@
  * recursion code should skip this directory.
  */
 static Dtype
-update_dirent_proc (void *callerdat, char *dir, char *repository, char 
*update_dir, List *entries)
+update_dirent_proc (void *callerdat, const char *dir, const char *repository,
+    const char *update_dir, List *entries)
 {
     if (ignore_directory (update_dir))
     {
@@ -941,11 +961,7 @@
        /* The directory exists.  Check to see if it has a CVS
           subdirectory.  */
 
-       cvsadmdir = xmalloc (strlen (dir) + 80);
-       strcpy (cvsadmdir, dir);
-       strcat (cvsadmdir, "/");
-       strcat (cvsadmdir, CVSADM);
-
+       (void) xasprintf (&cvsadmdir, "%s/%s", dir, CVSADM);
        if (!isdir (cvsadmdir))
        {
            /* We cannot successfully recurse into a directory without a CVS
@@ -967,8 +983,7 @@
        {
            char *tmp;
 
-           tmp = xmalloc (strlen (dir) + sizeof (CVSADM_ENTSTAT) + 10);
-           (void) sprintf (tmp, "%s/%s", dir, CVSADM_ENTSTAT);
+           (void) xasprintf (&tmp, "%s/%s", dir, CVSADM_ENTSTAT);
            if (unlink_file (tmp) < 0 && ! existence_error (errno))
                error (1, errno, "cannot remove file %s", tmp);
 #ifdef SERVER_SUPPORT
@@ -1007,7 +1022,8 @@
  */
 /* ARGSUSED */
 static int
-update_dirleave_proc (void *callerdat, char *dir, int err, char *update_dir, 
List *entries)
+update_dirleave_proc (void *callerdat, const char *dir, int err,
+    const char *update_dir, List *entries)
 {
     /* Delete the ignore list if it hasn't already been done.  */
     if (ignlist)
@@ -1071,7 +1087,7 @@
    existence of the CVS directory entry.  Zero otherwise.  If MIGHT_NOT_EXIST
    and the directory doesn't exist, then just return 0.  */
 int
-isemptydir (char *dir, int might_not_exist)
+isemptydir (const char *dir, int might_not_exist)
 {
     DIR *dirp;
     struct dirent *dp;
@@ -1209,11 +1225,7 @@
 #endif
        )
     {
-       backup = xmalloc (strlen (finfo->file)
-                         + sizeof (CVSADM)
-                         + sizeof (CVSPREFIX)
-                         + 10);
-       (void) sprintf (backup, "%s/%s%s", CVSADM, CVSPREFIX, finfo->file);
+       (void) xasprintf (&backup, "%s/%s%s", CVSADM, CVSPREFIX, finfo->file);
        if (isfile (finfo->file))
            rename_file (finfo->file, backup);
        else
@@ -1561,11 +1573,7 @@
        return 0;
     }
 
-    backup = xmalloc (strlen (finfo->file)
-                     + sizeof (CVSADM)
-                     + sizeof (CVSPREFIX)
-                     + 10);
-    (void) sprintf (backup, "%s/%s%s", CVSADM, CVSPREFIX, finfo->file);
+    (void) xasprintf (&backup, "%s/%s%s", CVSADM, CVSPREFIX, finfo->file);
     if (isfile (finfo->file))
         rename_file (finfo->file, backup);
     else
@@ -1575,16 +1583,8 @@
            error (0, errno, "cannot remove %s", backup);
     }
 
-    file1 = xmalloc (strlen (finfo->file)
-                    + sizeof (CVSADM)
-                    + sizeof (CVSPREFIX)
-                    + 10);
-    (void) sprintf (file1, "%s/%s%s-1", CVSADM, CVSPREFIX, finfo->file);
-    file2 = xmalloc (strlen (finfo->file)
-                    + sizeof (CVSADM)
-                    + sizeof (CVSPREFIX)
-                    + 10);
-    (void) sprintf (file2, "%s/%s%s-2", CVSADM, CVSPREFIX, finfo->file);
+    (void) xasprintf (&file1, "%s/%s%s-1", CVSADM, CVSPREFIX, finfo->file);
+    (void) xasprintf (&file2, "%s/%s%s-2", CVSADM, CVSPREFIX, finfo->file);
 
     fail = 0;
 
@@ -1882,11 +1882,8 @@
      * is the version of the file that the user was most up-to-date with
      * before the merge.
      */
-    backup = xmalloc (strlen (finfo->file)
-                     + strlen (vers->vn_user)
-                     + sizeof (BAKPREFIX)
-                     + 10);
-    (void) sprintf (backup, "%s%s.%s", BAKPREFIX, finfo->file, vers->vn_user);
+    (void) xasprintf (&backup, "%s%s.%s", BAKPREFIX, finfo->file,
+       vers->vn_user);
 
     if (unlink_file (backup) && !existence_error (errno))
        error (0, errno, "unable to remove %s", backup);
@@ -2248,8 +2245,7 @@
           cvs up -rbr -jbr2 could remove and readd the same file
         */
        /* save the rev since server_updated might invalidate it */
-       mrev = xmalloc (strlen (vers->vn_user) + 2);
-       sprintf (mrev, "-%s", vers->vn_user);
+       (void) xasprintf (&mrev, "-%s", vers->vn_user);
 #ifdef SERVER_SUPPORT
        if (server_active)
        {
@@ -2411,11 +2407,8 @@
      * is the version of the file that the user was most up-to-date with
      * before the merge.
      */
-    backup = xmalloc (strlen (finfo->file)
-                     + strlen (vers->vn_user)
-                     + sizeof (BAKPREFIX)
-                     + 10);
-    (void) sprintf (backup, "%s%s.%s", BAKPREFIX, finfo->file, vers->vn_user);
+    (void) xasprintf (&backup, "%s%s.%s", BAKPREFIX, finfo->file,
+       vers->vn_user);
 
     if (unlink_file (backup) < 0
        && !existence_error (errno))
@@ -2620,7 +2613,8 @@
  */
 
 int
-special_file_mismatch (struct file_info *finfo, char *rev1, char *rev2)
+special_file_mismatch (struct file_info *finfo, const char *rev1,
+    const char *rev2)
 {
 #ifdef PRESERVE_PERMISSIONS_SUPPORT
     struct stat sb;
Index: src/update.h
===================================================================
RCS file: /cvs/ccvs/src/update.h,v
retrieving revision 1.9
diff -u -u -r1.9 update.h
--- src/update.h        23 Jul 2003 20:42:26 -0000      1.9
+++ src/update.h        25 Oct 2003 02:17:44 -0000
@@ -10,11 +10,11 @@
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.  */
 
-int do_update ( int argc, char *argv[], char *xoptions, char *xtag,
-                      char *xdate, int xforce, int local, int xbuild,
+int do_update ( int argc, char *argv[], const char *xoptions, const char *xtag,
+                      const char *xdate, int xforce, int local, int xbuild,
                       int xaflag, int xprune, int xpipeout, int which,
-                      char *xjoin_rev1, char *xjoin_rev2,
-                      char *preload_update_dir, int xdotemplate,
-                      char*repository );
+                      const char *xjoin_rev1, const char *xjoin_rev2,
+                      const char *preload_update_dir, int xdotemplate,
+                      const char *repository );
 int joining (void);
-extern int isemptydir (char *dir, int might_not_exist);
+extern int isemptydir (const char *dir, int might_not_exist);
Index: src/vers_ts.c
===================================================================
RCS file: /cvs/ccvs/src/vers_ts.c,v
retrieving revision 1.52
diff -u -u -r1.52 vers_ts.c
--- src/vers_ts.c       24 Oct 2003 15:18:05 -0000      1.52
+++ src/vers_ts.c       25 Oct 2003 02:17:44 -0000
@@ -9,7 +9,7 @@
 #include "cvs.h"
 
 #ifdef SERVER_SUPPORT
-static void time_stamp_server (char *, Vers_TS *, Entnode *);
+static void time_stamp_server (const char *, Vers_TS *, Entnode *);
 #endif
 
 /* Fill in and return a Vers_TS structure for the file FINFO.
@@ -32,8 +32,8 @@
  *   Vers_TS structure for FINFO.
  */
 Vers_TS *
-Version_TS (struct file_info *finfo, char *options, char *tag, char *date,
-            int force_tag_match, int set_time)
+Version_TS (struct file_info *finfo, const char *options, const char *tag,
+           const char *date, int force_tag_match, int set_time)
 {
     Node *p;
     RCSNode *rcsdata;
@@ -141,9 +141,7 @@
           a file is binary.  */
        if( vers_ts->options != NULL )
            free( vers_ts->options );
-       vers_ts->options = xmalloc( strlen( rcsexpand ) + 3 );
-       strcpy( vers_ts->options, "-k" );
-       strcat( vers_ts->options, rcsexpand );
+       (void) xasprintf (&vers_ts->options, "-k%s", rcsexpand);
     }
     if( !vers_ts->options )
        vers_ts->options = xstrdup( "" );
@@ -276,7 +274,7 @@
 #define mark_unchanged(V)      ((V)->ts_user = xstrdup ((V)->ts_rcs))
 
 static void
-time_stamp_server (char *file, Vers_TS *vers_ts, Entnode *entdata)
+time_stamp_server (const char *file, Vers_TS *vers_ts, Entnode *entdata)
 {
     struct stat sb;
     char *cp;
@@ -339,7 +337,7 @@
  * allocates
  */
 char *
-time_stamp (char *file)
+time_stamp (const char *file)
 {
     struct stat sb;
     char *cp;
Index: src/watch.c
===================================================================
RCS file: /cvs/ccvs/src/watch.c,v
retrieving revision 1.40
diff -u -u -r1.40 watch.c
--- src/watch.c 23 Jul 2003 20:42:26 -0000      1.40
+++ src/watch.c 25 Oct 2003 02:17:44 -0000
@@ -32,7 +32,7 @@
 static struct addremove_args the_args;
 
 void
-watch_modify_watchers (char *file, struct addremove_args *what)
+watch_modify_watchers (const char *file, struct addremove_args *what)
 {
     char *curattr = fileattr_get0 (file, "_watchers");
     char *p;
@@ -222,11 +222,12 @@
     return 0;
 }
 
-static int addremove_filesdoneproc (void *, int, char *, char *,
+static int addremove_filesdoneproc (void *, int, const char *, const char *,
                                           List *);
 
 static int
-addremove_filesdoneproc (void *callerdat, int err, char *repository, char 
*update_dir, List *entries)
+addremove_filesdoneproc (void *callerdat, int err, const char *repository,
+    const char *update_dir, List *entries)
 {
     if (the_args.setting_default)
        watch_modify_watchers (NULL, &the_args);
@@ -333,7 +334,7 @@
        ( addremove_fileproc, addremove_filesdoneproc,
          (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL,
          argc, argv, local, W_LOCAL, 0, CVS_LOCK_NONE,
-         (char *) NULL, 1, (char *) NULL );
+         (const char *) NULL, 1, (const char *) NULL );
 
     Lock_Cleanup ();
     return err;
Index: src/watch.h
===================================================================
RCS file: /cvs/ccvs/src/watch.h,v
retrieving revision 1.5
diff -u -u -r1.5 watch.h
--- src/watch.h 23 Jul 2003 20:42:26 -0000      1.5
+++ src/watch.h 25 Oct 2003 02:17:44 -0000
@@ -45,7 +45,7 @@
 /* Modify the watchers for FILE.  *WHAT tells what to do to them.
    If FILE is NULL, modify default args (WHAT->SETTING_DEFAULT is
    not used).  */
-extern void watch_modify_watchers (char *file,
+extern void watch_modify_watchers (const char *file,
                                          struct addremove_args *what);
 
 extern int watch_add (int argc, char **argv);
Index: src/wrapper.c
===================================================================
RCS file: /cvs/ccvs/src/wrapper.c,v
retrieving revision 1.36
diff -u -u -r1.36 wrapper.c
--- src/wrapper.c       23 Jul 2003 20:42:26 -0000      1.36
+++ src/wrapper.c       25 Oct 2003 02:17:44 -0000
@@ -99,13 +99,9 @@
     {
        char *file;
 
-       file = xmalloc (strlen (current_parsed_root->directory)
-                       + sizeof (CVSROOTADM)
-                       + sizeof (CVSROOTADM_WRAPPER)
-                       + 3);
        /* Then add entries found in repository, if it exists.  */
-       (void) sprintf (file, "%s/%s/%s", current_parsed_root->directory, 
CVSROOTADM,
-                       CVSROOTADM_WRAPPER);
+       (void) xasprintf (&file, "%s/%s/%s", current_parsed_root->directory,
+           CVSROOTADM, CVSROOTADM_WRAPPER);
        if (isfile (file))
        {
            wrap_add_file(file,0);
@@ -214,22 +210,8 @@
         return;
     }
 
-    *line = xmalloc (strlen (wrap_list[i]->wildCard)
-                     + strlen ("\t")
-                     + strlen (" -k '")
-                     + (wrap_list[i]->rcsOption != NULL ? 
-                           strlen (wrap_list[i]->rcsOption) : 2)
-                     + strlen ("'")
-                     + 1);  /* leave room for '\0' */
-
-    strcpy (*line, wrap_list[i]->wildCard);
-    strcat (*line, " -k '");
-    if (wrap_list[i]->rcsOption != NULL)
-        strcat (*line, wrap_list[i]->rcsOption);
-    else
-        strcat (*line, "kv");
-    strcat (*line, "'");
-
+    (void) xasprintf (line, "%s -k '%s'", wrap_list[i]->wildCard,
+       wrap_list[i]->rcsOption != NULL ? wrap_list[i]->rcsOption : "kv");
     ++i;
 }
 #endif /* SERVER_SUPPORT || CLIENT_SUPPORT */
@@ -325,7 +307,7 @@
 void
 wrap_add (char *line, int isTemp)
 {
-    char *temp;
+    const char *temp;
     char ctemp;
     WrapperEntry e;
     char opt;
@@ -348,7 +330,7 @@
     ctemp=*line;
     *line='\0';
 
-    e.wildCard=xstrdup(temp);
+    e.wildCard=xstrdup (temp);
     *line=ctemp;
 
     while(*line){
@@ -510,16 +492,10 @@
     if (e == NULL || e->rcsOption == NULL || (*e->rcsOption == '\0'))
        return NULL;
 
-    buf = xmalloc (strlen (e->rcsOption) + 3);
     if (asflag)
-    {
-       strcpy (buf, "-k");
-       strcat (buf, e->rcsOption);
-    }
+       (void) xasprintf (&buf, "-k%s", e->rcsOption);
     else
-    {
-       strcpy (buf, e->rcsOption);
-    }
+       buf = xstrdup (e->rcsOption);
     return buf;
 }
 
@@ -537,13 +513,10 @@
        free (buf);
     buf = cvs_temp_name ();
 
-    args = xmalloc (strlen (e->tocvsFilter)
-                   + strlen (fileName)
-                   + strlen (buf));
-    /* FIXME: sprintf will blow up if the format string contains items other
+    /* FIXME: xasprintf will blow up if the format string contains items other
        than %s, or contains too many %s's.  We should instead be parsing
        e->tocvsFilter ourselves and giving a real error.  */
-    sprintf (args, e->tocvsFilter, fileName, buf);
+    (void) xasprintf (&args, e->tocvsFilter, fileName, buf);
     run_setup (args);
     run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY );
     free (args);
@@ -570,12 +543,10 @@
     if(e==NULL || e->fromcvsFilter==NULL)
        return;
 
-    args = xmalloc (strlen (e->fromcvsFilter)
-                   + strlen (fileName));
-    /* FIXME: sprintf will blow up if the format string contains items other
+    /* FIXME: xasprintf will blow up if the format string contains items other
        than %s, or contains too many %s's.  We should instead be parsing
        e->fromcvsFilter ourselves and giving a real error.  */
-    sprintf (args, e->fromcvsFilter, fileName);
+    (void) xasprintf (&args, e->fromcvsFilter, fileName);
     run_setup (args);
     run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL );
     free (args);
Index: src/zlib.c
===================================================================
RCS file: /cvs/ccvs/src/zlib.c,v
retrieving revision 1.16
diff -u -u -r1.16 zlib.c
--- src/zlib.c  19 Aug 2003 13:35:16 -0000      1.16
+++ src/zlib.c  25 Oct 2003 02:17:44 -0000
@@ -419,7 +419,7 @@
    it is an error we can't recover from.  */
 
 int
-gunzip_and_write (int fd, char *fullname, unsigned char *buf, size_t size)
+gunzip_and_write (int fd, const char *fullname, unsigned char *buf, size_t 
size)
 {
     size_t pos;
     z_stream zstr;
@@ -519,7 +519,8 @@
    recover from it).  LEVEL is the compression level (1-9).  */
 
 int
-read_and_gzip (int fd, char *fullname, unsigned char **buf, size_t *size, 
size_t *len, int level)
+read_and_gzip (int fd, const char *fullname, unsigned char **buf, size_t *size,
+    size_t *len, int level)
 {
     z_stream zstr;
     int zstatus;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]