/codebase/libs/xview/src/misc/expandpath.c

https://github.com/NCAR/lrose-core · C · 124 lines · 87 code · 11 blank · 26 comment · 44 complexity · 85af56a8ee2593da59be2abae5e32a16 MD5 · raw file

  1. #ifndef lint
  2. #ifdef sccs
  3. static char sccsid[] = "@(#)expandpath.c 20.16 93/06/28 SMI";
  4. #endif
  5. #endif
  6. /*
  7. * (c) Copyright 1989 Sun Microsystems, Inc. Sun design patents
  8. * pending in the U.S. and foreign countries. See LEGAL NOTICE
  9. * file for terms of the license.
  10. */
  11. /*
  12. * Sun Microsystems, Inc.
  13. */
  14. /*-
  15. Handles:
  16. ~/ => home dir
  17. ~user/ => user's home dir
  18. If the environment variable a = "foo" and b = "bar" then:
  19. $a => foo
  20. $a$b => foobar
  21. $a.c => foo.c
  22. xxx$a => xxxfoo
  23. ${a}! => foo!
  24. \$a => \$a
  25. */
  26. #include <sys/param.h>
  27. #include <sys/types.h>
  28. #include <sys/stat.h>
  29. #include <pwd.h>
  30. #include <ctype.h>
  31. #include <string.h>
  32. #include <xview_private/portable.h>
  33. /* input name in nm, pathname output to buf. */
  34. void
  35. expand_path(nm, buf)
  36. register char *nm, *buf;
  37. {
  38. register char *s, *d;
  39. char lnm[MAXPATHLEN];
  40. int q;
  41. register char *trimchars = "\n \t";
  42. char *getenv();
  43. /* Strip off leading & trailing whitespace and cr */
  44. while (XV_INDEX(trimchars, *nm) != NULL)
  45. nm++;
  46. s = nm + (q = strlen(nm)) - 1;
  47. while (q-- && XV_INDEX(trimchars, *s) != NULL)
  48. *s = '\0';
  49. s = nm;
  50. d = lnm;
  51. q = nm[0] == '\\' && nm[1] == '~';
  52. /* Expand inline environment variables */
  53. while (*d++ = *s) {
  54. if (*s == '\\') {
  55. if (*(d - 1) = *++s) {
  56. s++;
  57. continue;
  58. } else
  59. break;
  60. } else if (*s++ == '$') {
  61. register char *start = d;
  62. register braces = *s == '{';
  63. register char *value;
  64. while (*d++ = *s)
  65. if (braces ? *s == '}' : !(isalnum(*s) || *s == '_') )
  66. break;
  67. else
  68. s++;
  69. *--d = 0;
  70. value = getenv(braces ? start + 1 : start);
  71. if (value) {
  72. for (d = start - 1; *d++ = *value++;);
  73. d--;
  74. if (braces && *s)
  75. s++;
  76. }
  77. }
  78. }
  79. /* Expand ~ and ~user */
  80. nm = lnm;
  81. s = "";
  82. if (nm[0] == '~' && !q) { /* prefix ~ */
  83. if (nm[1] == '/' || nm[1] == 0) { /* ~/filename */
  84. if (s = getenv("HOME")) {
  85. if (*++nm)
  86. nm++;
  87. }
  88. } else { /* ~user/filename */
  89. register char *nnm;
  90. register struct passwd *pw;
  91. for (s = nm; *s && *s != '/'; s++);
  92. nnm = *s ? s + 1 : s;
  93. *s = 0;
  94. pw = (struct passwd *) getpwnam(nm + 1);
  95. if (pw == 0) {
  96. *s = '/';
  97. s = "";
  98. } else {
  99. nm = nnm;
  100. s = pw->pw_dir;
  101. }
  102. }
  103. }
  104. d = buf;
  105. if (*s) {
  106. while (*d++ = *s++);
  107. *(d - 1) = '/';
  108. }
  109. s = nm;
  110. while (*d++ = *s++);
  111. }