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