xref: /openbsd-src/gnu/usr.bin/cvs/src/subr.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /*
2  * Copyright (c) 1992, Brian Berliner and Jeff Polk
3  * Copyright (c) 1989-1992, Brian Berliner
4  *
5  * You may distribute under the terms of the GNU General Public License as
6  * specified in the README file that comes with the CVS source distribution.
7  *
8  * Various useful functions for the CVS support code.
9  */
10 
11 #include "cvs.h"
12 #include "getline.h"
13 
14 extern char *getlogin ();
15 
16 /*
17  * malloc some data and die if it fails
18  */
19 void *
20 xmalloc (bytes)
21     size_t bytes;
22 {
23     char *cp;
24 
25     /* Parts of CVS try to xmalloc zero bytes and then free it.  Some
26        systems have a malloc which returns NULL for zero byte
27        allocations but a free which can't handle NULL, so compensate. */
28     if (bytes == 0)
29 	bytes = 1;
30 
31     cp = malloc (bytes);
32     if (cp == NULL)
33     {
34 	char buf[80];
35 	sprintf (buf, "out of memory; can not allocate %lu bytes",
36 		 (unsigned long) bytes);
37 	error (1, 0, buf);
38     }
39     return (cp);
40 }
41 
42 /*
43  * realloc data and die if it fails [I've always wanted to have "realloc" do
44  * a "malloc" if the argument is NULL, but you can't depend on it.  Here, I
45  * can *force* it.
46  */
47 void *
48 xrealloc (ptr, bytes)
49     void *ptr;
50     size_t bytes;
51 {
52     char *cp;
53 
54     if (!ptr)
55 	cp = malloc (bytes);
56     else
57 	cp = realloc (ptr, bytes);
58 
59     if (cp == NULL)
60     {
61 	char buf[80];
62 	sprintf (buf, "out of memory; can not reallocate %lu bytes",
63 		 (unsigned long) bytes);
64 	error (1, 0, buf);
65     }
66     return (cp);
67 }
68 
69 /* Two constants which tune expand_string.  Having MIN_INCR as large
70    as 1024 might waste a bit of memory, but it shouldn't be too bad
71    (CVS used to allocate arrays of, say, 3000, PATH_MAX (8192, often),
72    or other such sizes).  Probably anything which is going to allocate
73    memory which is likely to get as big as MAX_INCR shouldn't be doing
74    it in one block which must be contiguous, but since getrcskey does
75    so, we might as well limit the wasted memory to MAX_INCR or so
76    bytes.
77 
78    MIN_INCR and MAX_INCR should both be powers of two and we generally
79    try to keep our allocations to powers of two for the most part.
80    Most malloc implementations these days tend to like that.  */
81 
82 #define MIN_INCR 1024
83 #define MAX_INCR (2*1024*1024)
84 
85 /* *STRPTR is a pointer returned from malloc (or NULL), pointing to *N
86    characters of space.  Reallocate it so that points to at least
87    NEWSIZE bytes of space.  Gives a fatal error if out of memory;
88    if it returns it was successful.  */
89 void
90 expand_string (strptr, n, newsize)
91     char **strptr;
92     size_t *n;
93     size_t newsize;
94 {
95     if (*n < newsize)
96     {
97 	while (*n < newsize)
98 	{
99 	    if (*n < MIN_INCR)
100 		*n = MIN_INCR;
101 	    else if (*n >= MAX_INCR)
102 		*n += MAX_INCR;
103 	    else
104 	    {
105 		*n *= 2;
106 		if (*n > MAX_INCR)
107 		    *n = MAX_INCR;
108 	    }
109 	}
110 	*strptr = xrealloc (*strptr, *n);
111     }
112 }
113 
114 /*
115  * Duplicate a string, calling xmalloc to allocate some dynamic space
116  */
117 char *
118 xstrdup (str)
119     const char *str;
120 {
121     char *s;
122 
123     if (str == NULL)
124 	return ((char *) NULL);
125     s = xmalloc (strlen (str) + 1);
126     (void) strcpy (s, str);
127     return (s);
128 }
129 
130 /* Remove trailing newlines from STRING, destructively. */
131 void
132 strip_trailing_newlines (str)
133      char *str;
134 {
135     int len;
136     len = strlen (str) - 1;
137 
138     while (str[len] == '\n')
139 	str[len--] = '\0';
140 }
141 
142 /* Return the number of levels that path ascends above where it starts.
143    For example:
144    "../../foo" -> 2
145    "foo/../../bar" -> 1
146    */
147 /* FIXME: Should be using ISDIRSEP, last_component, or some other
148    mechanism which is more general than just looking at slashes,
149    particularly for the client.c caller.  The server.c caller might
150    want something different, so be careful.  */
151 int
152 pathname_levels (path)
153     char *path;
154 {
155     char *p;
156     char *q;
157     int level;
158     int max_level;
159 
160     max_level = 0;
161     p = path;
162     level = 0;
163     do
164     {
165 	q = strchr (p, '/');
166 	if (q != NULL)
167 	    ++q;
168 	if (p[0] == '.' && p[1] == '.' && (p[2] == '\0' || p[2] == '/'))
169 	{
170 	    --level;
171 	    if (-level > max_level)
172 		max_level = -level;
173 	}
174 	else if (p[0] == '\0' || p[0] == '/' ||
175 		 (p[0] == '.' && (p[1] == '\0' || p[1] == '/')))
176 	    ;
177 	else
178 	    ++level;
179 	p = q;
180     } while (p != NULL);
181     return max_level;
182 }
183 
184 
185 /* Free a vector, where (*ARGV)[0], (*ARGV)[1], ... (*ARGV)[*PARGC - 1]
186    are malloc'd and so is *ARGV itself.  Such a vector is allocated by
187    line2argv or expand_wild, for example.  */
188 void
189 free_names (pargc, argv)
190     int *pargc;
191     char **argv;
192 {
193     register int i;
194 
195     for (i = 0; i < *pargc; i++)
196     {					/* only do through *pargc */
197 	free (argv[i]);
198     }
199     free (argv);
200     *pargc = 0;				/* and set it to zero when done */
201 }
202 
203 /* Convert LINE into arguments separated by SEPCHARS.  Set *ARGC
204    to the number of arguments found, and (*ARGV)[0] to the first argument,
205    (*ARGV)[1] to the second, etc.  *ARGV is malloc'd and so are each of
206    (*ARGV)[0], (*ARGV)[1], ...  Use free_names() to return the memory
207    allocated here back to the free pool.  */
208 void
209 line2argv (pargc, argv, line, sepchars)
210     int *pargc;
211     char ***argv;
212     char *line;
213     char *sepchars;
214 {
215     char *cp;
216     /* Could make a case for size_t or some other unsigned type, but
217        we'll stick with int to avoid signed/unsigned warnings when
218        comparing with *pargc.  */
219     int argv_allocated;
220 
221     /* Small for testing.  */
222     argv_allocated = 1;
223     *argv = (char **) xmalloc (argv_allocated * sizeof (**argv));
224 
225     *pargc = 0;
226     for (cp = strtok (line, sepchars); cp; cp = strtok ((char *) NULL, sepchars))
227     {
228 	if (*pargc == argv_allocated)
229 	{
230 	    argv_allocated *= 2;
231 	    *argv = xrealloc (*argv, argv_allocated * sizeof (**argv));
232 	}
233 	(*argv)[*pargc] = xstrdup (cp);
234 	(*pargc)++;
235     }
236 }
237 
238 /*
239  * Returns the number of dots ('.') found in an RCS revision number
240  */
241 int
242 numdots (s)
243     const char *s;
244 {
245     int dots = 0;
246 
247     for (; *s; s++)
248     {
249 	if (*s == '.')
250 	    dots++;
251     }
252     return (dots);
253 }
254 
255 /* Compare revision numbers REV1 and REV2 by consecutive fields.
256    Return negative, zero, or positive in the manner of strcmp.  The
257    two revision numbers must have the same number of fields, or else
258    compare_revnums will return an inaccurate result. */
259 int
260 compare_revnums (rev1, rev2)
261     const char *rev1;
262     const char *rev2;
263 {
264     const char *s, *sp;
265     const char *t, *tp;
266     char *snext, *tnext;
267     int result = 0;
268 
269     sp = s = rev1;
270     tp = t = rev2;
271     while (result == 0)
272     {
273 	result = strtoul (sp, &snext, 10) - strtoul (tp, &tnext, 10);
274 	if (*snext == '\0' || *tnext == '\0')
275 	    break;
276 	sp = snext + 1;
277 	tp = tnext + 1;
278     }
279 
280     return result;
281 }
282 
283 char *
284 increment_revnum (rev)
285     const char *rev;
286 {
287     char *newrev, *p;
288     int lastfield;
289     size_t len = strlen (rev);
290 
291     newrev = (char *) xmalloc (len + 2);
292     memcpy (newrev, rev, len + 1);
293     p = strrchr (newrev, '.');
294     if (p == NULL)
295     {
296 	free (newrev);
297 	return NULL;
298     }
299     lastfield = atoi (++p);
300     sprintf (p, "%d", lastfield + 1);
301 
302     return newrev;
303 }
304 
305 /* Return the username by which the caller should be identified in
306    CVS, in contexts such as the author field of RCS files, various
307    logs, etc.  */
308 char *
309 getcaller ()
310 {
311 #ifndef SYSTEM_GETCALLER
312     static char *cache;
313     struct passwd *pw;
314     uid_t uid;
315 #endif
316 
317     /* If there is a CVS username, return it.  */
318 #ifdef AUTH_SERVER_SUPPORT
319     if (CVS_Username != NULL)
320 	return CVS_Username;
321 #endif
322 
323 #ifdef SYSTEM_GETCALLER
324     return SYSTEM_GETCALLER ();
325 #else
326     /* Get the caller's login from his uid.  If the real uid is "root"
327        try LOGNAME USER or getlogin(). If getlogin() and getpwuid()
328        both fail, return the uid as a string.  */
329 
330     if (cache != NULL)
331 	return cache;
332 
333     uid = getuid ();
334     if (uid == (uid_t) 0)
335     {
336 	char *name;
337 
338 	/* super-user; try getlogin() to distinguish */
339 	if (((name = getlogin ()) || (name = getenv("LOGNAME")) ||
340 	     (name = getenv("USER"))) && *name)
341 	{
342 	    cache = xstrdup (name);
343 	    return cache;
344 	}
345     }
346     if ((pw = (struct passwd *) getpwuid (uid)) == NULL)
347     {
348 	char uidname[20];
349 
350 	(void) sprintf (uidname, "uid%lu", (unsigned long) uid);
351 	cache = xstrdup (uidname);
352 	return cache;
353     }
354     cache = xstrdup (pw->pw_name);
355     return cache;
356 #endif
357 }
358 
359 #ifdef lint
360 #ifndef __GNUC__
361 /* ARGSUSED */
362 time_t
363 get_date (date, now)
364     char *date;
365     struct timeb *now;
366 {
367     time_t foo = 0;
368 
369     return (foo);
370 }
371 #endif
372 #endif
373 
374 /* Given two revisions, find their greatest common ancestor.  If the
375    two input revisions exist, then rcs guarantees that the gca will
376    exist.  */
377 
378 char *
379 gca (rev1, rev2)
380     const char *rev1;
381     const char *rev2;
382 {
383     int dots;
384     char *gca;
385     const char *p[2];
386     int j[2];
387     char *retval;
388 
389     if (rev1 == NULL || rev2 == NULL)
390     {
391 	error (0, 0, "sanity failure in gca");
392 	abort();
393     }
394 
395     /* The greatest common ancestor will have no more dots, and numbers
396        of digits for each component no greater than the arguments.  Therefore
397        this string will be big enough.  */
398     gca = xmalloc (strlen (rev1) + strlen (rev2) + 100);
399 
400     /* walk the strings, reading the common parts. */
401     gca[0] = '\0';
402     p[0] = rev1;
403     p[1] = rev2;
404     do
405     {
406 	int i;
407 	char c[2];
408 	char *s[2];
409 
410 	for (i = 0; i < 2; ++i)
411 	{
412 	    /* swap out the dot */
413 	    s[i] = strchr (p[i], '.');
414 	    if (s[i] != NULL) {
415 		c[i] = *s[i];
416 	    }
417 
418 	    /* read an int */
419 	    j[i] = atoi (p[i]);
420 
421 	    /* swap back the dot... */
422 	    if (s[i] != NULL) {
423 		*s[i] = c[i];
424 		p[i] = s[i] + 1;
425 	    }
426 	    else
427 	    {
428 		/* or mark us at the end */
429 		p[i] = NULL;
430 	    }
431 
432 	}
433 
434 	/* use the lowest. */
435 	(void) sprintf (gca + strlen (gca), "%d.",
436 			j[0] < j[1] ? j[0] : j[1]);
437 
438     } while (j[0] == j[1]
439 	     && p[0] != NULL
440 	     && p[1] != NULL);
441 
442     /* back up over that last dot. */
443     gca[strlen(gca) - 1] = '\0';
444 
445     /* numbers differ, or we ran out of strings.  we're done with the
446        common parts.  */
447 
448     dots = numdots (gca);
449     if (dots == 0)
450     {
451 	/* revisions differ in trunk major number.  */
452 
453 	char *q;
454 	const char *s;
455 
456 	s = (j[0] < j[1]) ? p[0] : p[1];
457 
458 	if (s == NULL)
459 	{
460 	    /* we only got one number.  this is strange.  */
461 	    error (0, 0, "bad revisions %s or %s", rev1, rev2);
462 	    abort();
463 	}
464 	else
465 	{
466 	    /* we have a minor number.  use it.  */
467 	    q = gca + strlen (gca);
468 
469 	    *q++ = '.';
470 	    for ( ; *s != '.' && *s != '\0'; )
471 		*q++ = *s++;
472 
473 	    *q = '\0';
474 	}
475     }
476     else if ((dots & 1) == 0)
477     {
478 	/* if we have an even number of dots, then we have a branch.
479 	   remove the last number in order to make it a revision.  */
480 
481 	char *s;
482 
483 	s = strrchr(gca, '.');
484 	*s = '\0';
485     }
486 
487     retval = xstrdup (gca);
488     free (gca);
489     return retval;
490 }
491 
492 /* Give fatal error if REV is numeric and ARGC,ARGV imply we are
493    planning to operate on more than one file.  The current directory
494    should be the working directory.  Note that callers assume that we
495    will only be checking the first character of REV; it need not have
496    '\0' at the end of the tag name and other niceties.  Right now this
497    is only called from admin.c, but if people like the concept it probably
498    should also be called from diff -r, update -r, get -r, and log -r.  */
499 
500 void
501 check_numeric (rev, argc, argv)
502     const char *rev;
503     int argc;
504     char **argv;
505 {
506     if (rev == NULL || !isdigit ((unsigned char) *rev))
507 	return;
508 
509     /* Note that the check for whether we are processing more than one
510        file is (basically) syntactic; that is, we don't behave differently
511        depending on whether a directory happens to contain only a single
512        file or whether it contains more than one.  I strongly suspect this
513        is the least confusing behavior.  */
514     if (argc != 1
515 	|| (!wrap_name_has (argv[0], WRAP_TOCVS) && isdir (argv[0])))
516     {
517 	error (0, 0, "while processing more than one file:");
518 	error (1, 0, "attempt to specify a numeric revision");
519     }
520 }
521 
522 /*
523  *  Sanity checks and any required fix-up on message passed to RCS via '-m'.
524  *  RCS 5.7 requires that a non-total-whitespace, non-null message be provided
525  *  with '-m'.  Returns a newly allocated, non-empty buffer with whitespace
526  *  stripped from end of lines and end of buffer.
527  *
528  *  TODO: We no longer use RCS to manage repository files, so maybe this
529  *  nonsense about non-empty log fields can be dropped.
530  */
531 char *
532 make_message_rcslegal (message)
533      char *message;
534 {
535     char *dst, *dp, *mp;
536 
537     if (message == NULL) message = "";
538 
539     /* Strip whitespace from end of lines and end of string. */
540     dp = dst = (char *) xmalloc (strlen (message) + 1);
541     for (mp = message; *mp != '\0'; ++mp)
542     {
543 	if (*mp == '\n')
544 	{
545 	    /* At end-of-line; backtrack to last non-space. */
546 	    while (dp > dst && (dp[-1] == ' ' || dp[-1] == '\t'))
547 		--dp;
548 	}
549 	*dp++ = *mp;
550     }
551 
552     /* Backtrack to last non-space at end of string, and truncate. */
553     while (dp > dst && isspace ((unsigned char) dp[-1]))
554 	--dp;
555     *dp = '\0';
556 
557     /* After all that, if there was no non-space in the string,
558        substitute a non-empty message. */
559     if (*dst == '\0')
560     {
561 	free (dst);
562 	dst = xstrdup ("*** empty log message ***");
563     }
564 
565     return dst;
566 }
567 
568 /* Does the file FINFO contain conflict markers?  The whole concept
569    of looking at the contents of the file to figure out whether there are
570    unresolved conflicts is kind of bogus (people do want to manage files
571    which contain those patterns not as conflict markers), but for now it
572    is what we do.  */
573 int
574 file_has_markers (finfo)
575     const struct file_info *finfo;
576 {
577     FILE *fp;
578     char *line = NULL;
579     size_t line_allocated = 0;
580     int result;
581 
582     result = 0;
583     fp = CVS_FOPEN (finfo->file, "r");
584     if (fp == NULL)
585 	error (1, errno, "cannot open %s", finfo->fullname);
586     while (getline (&line, &line_allocated, fp) > 0)
587     {
588 	if (strncmp (line, RCS_MERGE_PAT_1, sizeof RCS_MERGE_PAT_1 - 1) == 0 ||
589 	    strncmp (line, RCS_MERGE_PAT_2, sizeof RCS_MERGE_PAT_2 - 1) == 0 ||
590 	    strncmp (line, RCS_MERGE_PAT_3, sizeof RCS_MERGE_PAT_3 - 1) == 0)
591 	{
592 	    result = 1;
593 	    goto out;
594 	}
595     }
596     if (ferror (fp))
597 	error (0, errno, "cannot read %s", finfo->fullname);
598 out:
599     if (fclose (fp) < 0)
600 	error (0, errno, "cannot close %s", finfo->fullname);
601     if (line != NULL)
602 	free (line);
603     return result;
604 }
605 
606 /* Read the entire contents of the file NAME into *BUF.
607    If NAME is NULL, read from stdin.  *BUF
608    is a pointer returned from malloc (or NULL), pointing to *BUFSIZE
609    bytes of space.  The actual size is returned in *LEN.  On error,
610    give a fatal error.  The name of the file to use in error messages
611    (typically will include a directory if we have changed directory)
612    is FULLNAME.  MODE is "r" for text or "rb" for binary.  */
613 
614 void
615 get_file (name, fullname, mode, buf, bufsize, len)
616     const char *name;
617     const char *fullname;
618     const char *mode;
619     char **buf;
620     size_t *bufsize;
621     size_t *len;
622 {
623     struct stat s;
624     size_t nread;
625     char *tobuf;
626     FILE *e;
627     size_t filesize;
628 
629     if (name == NULL)
630     {
631 	e = stdin;
632 	filesize = 100;	/* force allocation of minimum buffer */
633     }
634     else
635     {
636 	/* Although it would be cleaner in some ways to just read
637 	   until end of file, reallocating the buffer, this function
638 	   does get called on files in the working directory which can
639 	   be of arbitrary size, so I think we better do all that
640 	   extra allocation.  */
641 
642 	if (CVS_STAT (name, &s) < 0)
643 	    error (1, errno, "can't stat %s", fullname);
644 
645 	/* Convert from signed to unsigned.  */
646 	filesize = s.st_size;
647 
648 	e = open_file (name, mode);
649     }
650 
651     if (*buf == NULL || *bufsize <= filesize)
652     {
653 	*bufsize = filesize + 1;
654 	*buf = xrealloc (*buf, *bufsize);
655     }
656 
657     tobuf = *buf;
658     nread = 0;
659     while (1)
660     {
661 	size_t got;
662 
663 	got = fread (tobuf, 1, *bufsize - (tobuf - *buf), e);
664 	if (ferror (e))
665 	    error (1, errno, "can't read %s", fullname);
666 	nread += got;
667 	tobuf += got;
668 
669 	if (feof (e))
670 	    break;
671 
672 	/* Allocate more space if needed.  */
673 	if (tobuf == *buf + *bufsize)
674 	{
675 	    int c;
676 	    long off;
677 
678 	    c = getc (e);
679 	    if (c == EOF)
680 		break;
681 	    off = tobuf - *buf;
682 	    expand_string (buf, bufsize, *bufsize + 100);
683 	    tobuf = *buf + off;
684 	    *tobuf++ = c;
685 	    ++nread;
686 	}
687     }
688 
689     if (e != stdin && fclose (e) < 0)
690 	error (0, errno, "cannot close %s", fullname);
691 
692     *len = nread;
693 
694     /* Force *BUF to be large enough to hold a null terminator. */
695     if (nread == *bufsize)
696 	expand_string (buf, bufsize, *bufsize + 1);
697     (*buf)[nread] = '\0';
698 }
699 
700 
701 /* Follow a chain of symbolic links to its destination.  FILENAME
702    should be a handle to a malloc'd block of memory which contains the
703    beginning of the chain.  This routine will replace the contents of
704    FILENAME with the destination (a real file).  */
705 
706 void
707 resolve_symlink (filename)
708      char **filename;
709 {
710     if ((! filename) || (! *filename))
711 	return;
712 
713     while (islink (*filename))
714     {
715 	char *newname;
716 #ifdef HAVE_READLINK
717 	/* The clean thing to do is probably to have each filesubr.c
718 	   implement this (with an error if not supported by the
719 	   platform, in which case islink would presumably return 0).
720 	   But that would require editing each filesubr.c and so the
721 	   expedient hack seems to be looking at HAVE_READLINK.  */
722 	newname = xreadlink (*filename);
723 #else
724 	error (1, 0, "internal error: islink doesn't like readlink");
725 #endif
726 
727 	if (isabsolute (newname))
728 	{
729 	    free (*filename);
730 	    *filename = newname;
731 	}
732 	else
733 	{
734 	    char *oldname = last_component (*filename);
735 	    int dirlen = oldname - *filename;
736 	    char *fullnewname = xmalloc (dirlen + strlen (newname) + 1);
737 	    strncpy (fullnewname, *filename, dirlen);
738 	    strcpy (fullnewname + dirlen, newname);
739 	    free (newname);
740 	    free (*filename);
741 	    *filename = fullnewname;
742 	}
743     }
744 }
745 
746 /*
747  * Rename a file to an appropriate backup name based on BAKPREFIX.
748  * If suffix non-null, then ".<suffix>" is appended to the new name.
749  *
750  * Returns the new name, which caller may free() if desired.
751  */
752 char *
753 backup_file (filename, suffix)
754      const char *filename;
755      const char *suffix;
756 {
757     char *backup_name;
758 
759     if (suffix == NULL)
760     {
761         backup_name = xmalloc (sizeof (BAKPREFIX) + strlen (filename) + 1);
762         sprintf (backup_name, "%s%s", BAKPREFIX, filename);
763     }
764     else
765     {
766         backup_name = xmalloc (sizeof (BAKPREFIX)
767                                + strlen (filename)
768                                + strlen (suffix)
769                                + 2);  /* one for dot, one for trailing '\0' */
770         sprintf (backup_name, "%s%s.%s", BAKPREFIX, filename, suffix);
771     }
772 
773     if (isfile (filename))
774         copy_file (filename, backup_name);
775 
776     return backup_name;
777 }
778 
779