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