/contrib/cvs/src/subr.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 968 lines · 638 code · 117 blank · 213 comment · 173 complexity · ea91409b66d4d9233d9e88e461d817bc MD5 · raw file

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